From 1ca0a2bdc0cc9ba494296b20d3b667a64ec82d3b Mon Sep 17 00:00:00 2001 From: Patrick Date: Wed, 11 Dec 2024 22:23:58 +0100 Subject: [PATCH] Initial setup for NPCs and their pathfinding. --- export_presets.cfg | 64 ++++++++++++++++++++++++++++++++++++ scenes/entities/npc.tscn | 24 ++++++++++++++ scenes/entities/player.tscn | 4 +++ scenes/maps/testmap.tscn | 65 ++++++++++++++++++++++++++++++++++--- scripts/entities/npc.gd | 44 +++++++++++++++++++++++++ scripts/entities/player.gd | 10 ++++-- 6 files changed, 204 insertions(+), 7 deletions(-) create mode 100644 scenes/entities/npc.tscn create mode 100644 scripts/entities/npc.gd diff --git a/export_presets.cfg b/export_presets.cfg index e69de29..c825ad2 100644 --- a/export_presets.cfg +++ b/export_presets.cfg @@ -0,0 +1,64 @@ +[preset.0] + +name="Windows Desktop" +platform="Windows Desktop" +runnable=true +advanced_options=false +dedicated_server=false +custom_features="" +export_filter="all_resources" +include_filter="" +exclude_filter="" +export_path="../../../../home/patrick/Desktop/Hotel Madness.exe" +encryption_include_filters="" +encryption_exclude_filters="" +encrypt_pck=false +encrypt_directory=false +script_export_mode=2 + +[preset.0.options] + +custom_template/debug="" +custom_template/release="" +debug/export_console_wrapper=1 +binary_format/embed_pck=true +texture_format/s3tc_bptc=true +texture_format/etc2_astc=false +binary_format/architecture="x86_64" +codesign/enable=false +codesign/timestamp=true +codesign/timestamp_server_url="" +codesign/digest_algorithm=1 +codesign/description="" +codesign/custom_options=PackedStringArray() +application/modify_resources=true +application/icon="" +application/console_wrapper_icon="" +application/icon_interpolation=4 +application/file_version="" +application/product_version="" +application/company_name="" +application/product_name="" +application/file_description="" +application/copyright="" +application/trademarks="" +application/export_angle=0 +application/export_d3d12=0 +application/d3d12_agility_sdk_multiarch=true +ssh_remote_deploy/enabled=false +ssh_remote_deploy/host="user@host_ip" +ssh_remote_deploy/port="22" +ssh_remote_deploy/extra_args_ssh="" +ssh_remote_deploy/extra_args_scp="" +ssh_remote_deploy/run_script="Expand-Archive -LiteralPath '{temp_dir}\\{archive_name}' -DestinationPath '{temp_dir}' +$action = New-ScheduledTaskAction -Execute '{temp_dir}\\{exe_name}' -Argument '{cmd_args}' +$trigger = New-ScheduledTaskTrigger -Once -At 00:00 +$settings = New-ScheduledTaskSettingsSet +$task = New-ScheduledTask -Action $action -Trigger $trigger -Settings $settings +Register-ScheduledTask godot_remote_debug -InputObject $task -Force:$true +Start-ScheduledTask -TaskName godot_remote_debug +while (Get-ScheduledTask -TaskName godot_remote_debug | ? State -eq running) { Start-Sleep -Milliseconds 100 } +Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue" +ssh_remote_deploy/cleanup_script="Stop-ScheduledTask -TaskName godot_remote_debug -ErrorAction:SilentlyContinue +Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue +Remove-Item -Recurse -Force '{temp_dir}'" diff --git a/scenes/entities/npc.tscn b/scenes/entities/npc.tscn new file mode 100644 index 0000000..7a09ef6 --- /dev/null +++ b/scenes/entities/npc.tscn @@ -0,0 +1,24 @@ +[gd_scene load_steps=5 format=3 uid="uid://cvnjpnvchvakj"] + +[ext_resource type="Script" path="res://scripts/entities/npc.gd" id="1_jvyx6"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_e5nrh"] +albedo_color = Color(1, 0, 0, 1) + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_qcrlh"] +material = SubResource("StandardMaterial3D_e5nrh") + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_am313"] + +[node name="Npc" type="CharacterBody3D"] +script = ExtResource("1_jvyx6") + +[node name="MeshInstance3D" type="MeshInstance3D" parent="."] +mesh = SubResource("CapsuleMesh_qcrlh") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="."] +shape = SubResource("CapsuleShape3D_am313") + +[node name="NavigationAgent3D" type="NavigationAgent3D" parent="."] +avoidance_enabled = true +height = 2.0 diff --git a/scenes/entities/player.tscn b/scenes/entities/player.tscn index f0d4c5c..4bfb2a4 100644 --- a/scenes/entities/player.tscn +++ b/scenes/entities/player.tscn @@ -17,3 +17,7 @@ shape = SubResource("CapsuleShape3D_7frjr") [node name="Camera3D" type="Camera3D" parent="."] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0) + +[node name="Label" type="Label" parent="."] +offset_right = 40.0 +offset_bottom = 23.0 diff --git a/scenes/maps/testmap.tscn b/scenes/maps/testmap.tscn index 97ef0c4..899341a 100644 --- a/scenes/maps/testmap.tscn +++ b/scenes/maps/testmap.tscn @@ -1,17 +1,24 @@ -[gd_scene load_steps=4 format=3 uid="uid://cbyee7drds7qu"] +[gd_scene load_steps=8 format=3 uid="uid://cbyee7drds7qu"] [ext_resource type="Script" path="res://scripts/maps/map.gd" id="1_4npcs"] [ext_resource type="PackedScene" uid="uid://bsghm187n6ykx" path="res://scenes/objects/closet.tscn" id="2_yvpvm"] +[ext_resource type="PackedScene" uid="uid://cvnjpnvchvakj" path="res://scenes/entities/npc.tscn" id="3_x3gyc"] [sub_resource type="Environment" id="Environment_pq0iv"] +[sub_resource type="NavigationMesh" id="NavigationMesh_hqhxb"] +vertices = PackedVector3Array(-49.5, 1, -49.5, -49.5, 1, 49.5, 49.5, 1, 49.5, 49.5, 1, -49.5) +polygons = [PackedInt32Array(3, 2, 0), PackedInt32Array(0, 2, 1)] + +[sub_resource type="BoxMesh" id="BoxMesh_kw2od"] +size = Vector3(100, 1, 100) + +[sub_resource type="BoxShape3D" id="BoxShape3D_rnmx0"] +size = Vector3(100, 1, 100) + [node name="Testmap" type="Node3D"] script = ExtResource("1_4npcs") -[node name="CSGBox3D" type="CSGBox3D" parent="."] -use_collision = true -size = Vector3(50, 1, 50) - [node name="PlayerSpawn" type="Node3D" parent="."] [node name="0" type="Node3D" parent="PlayerSpawn"] @@ -31,3 +38,51 @@ environment = SubResource("Environment_pq0iv") [node name="Closet" parent="." instance=ExtResource("2_yvpvm")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, 10, 2) + +[node name="Npc7" parent="." instance=ExtResource("3_x3gyc")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 40, 30, 0) + +[node name="Npc8" parent="." instance=ExtResource("3_x3gyc")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 30, -40) + +[node name="Npc9" parent="." instance=ExtResource("3_x3gyc")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 40, 30, -40) + +[node name="Npc10" parent="." instance=ExtResource("3_x3gyc")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -40, 30, -40) + +[node name="Npc11" parent="." instance=ExtResource("3_x3gyc")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -40, 30, 40) + +[node name="Npc12" parent="." instance=ExtResource("3_x3gyc")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 40, 30, 40) + +[node name="Npc6" parent="." instance=ExtResource("3_x3gyc")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 40, 20, 0) + +[node name="Npc5" parent="." instance=ExtResource("3_x3gyc")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 20, -40) + +[node name="Npc4" parent="." instance=ExtResource("3_x3gyc")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 40, 20, -40) + +[node name="Npc3" parent="." instance=ExtResource("3_x3gyc")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -40, 20, -40) + +[node name="Npc2" parent="." instance=ExtResource("3_x3gyc")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -40, 20, 40) + +[node name="Npc1" parent="." instance=ExtResource("3_x3gyc")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 40, 20, 40) + +[node name="NavigationRegion3D" type="NavigationRegion3D" parent="."] +navigation_mesh = SubResource("NavigationMesh_hqhxb") + +[node name="StaticBody3D" type="StaticBody3D" parent="NavigationRegion3D"] + +[node name="MeshInstance3D" type="MeshInstance3D" parent="NavigationRegion3D/StaticBody3D"] +mesh = SubResource("BoxMesh_kw2od") +skeleton = NodePath("../..") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="NavigationRegion3D/StaticBody3D"] +shape = SubResource("BoxShape3D_rnmx0") diff --git a/scripts/entities/npc.gd b/scripts/entities/npc.gd new file mode 100644 index 0000000..c1f9b15 --- /dev/null +++ b/scripts/entities/npc.gd @@ -0,0 +1,44 @@ +extends CharacterBody3D + +var movement_speed: float = 3.0 + +var target: CharacterBody3D +var movement_target_position: Vector3 + +var skip: bool = false + +@onready var navigation_agent: NavigationAgent3D = $NavigationAgent3D + +func _ready() -> void: + first_frame.call_deferred() + +func first_frame() -> void: + actor_setup(999999999) + +# determines the closest player and navigate. +func actor_setup(lowest_distance: float) -> void: + if !skip: + for child: Node in get_tree().root.get_node("/root/Testmap").get_children(): + if child is Node3D: + if child.has_method("playerstub") and position.distance_to((child as Node3D).position) < lowest_distance: + target = child + skip = true + + var dist: float = target.position.distance_to(movement_target_position) + if movement_target_position != target.position and (dist > 5 or position.distance_to(target.position) <= 5 or position.distance_to(movement_target_position) <= 5): + movement_target_position = target.position + navigation_agent.set_target_position(movement_target_position) + +func _physics_process(_delta: float) -> void: + actor_setup(position.distance_to(target.position)) + + if navigation_agent.is_navigation_finished(): + return + + var current_agent_position: Vector3 = global_position + var next_path_position: Vector3 = navigation_agent.get_next_path_position() + + velocity = current_agent_position.direction_to(next_path_position) * movement_speed + + if move_and_slide(): + pass diff --git a/scripts/entities/player.gd b/scripts/entities/player.gd index 79665c0..9b7c941 100644 --- a/scripts/entities/player.gd +++ b/scripts/entities/player.gd @@ -10,8 +10,7 @@ const JUMP_VELOCITY: float = 4.5 var activated: bool = false var freecam: bool = false -@onready -var camera: Camera3D = $Camera3D +@onready var camera: Camera3D = $Camera3D var camera_rotation: Vector2 = Vector2(0,0) func _ready() -> void: @@ -55,6 +54,9 @@ func _physics_process(delta: float) -> void: if move_and_slide(): pass + var fps_counter: Label = $Label + fps_counter.text = str(Engine.get_frames_per_second()) + Networking.player_sync_call(position, rotation) func _input(event: InputEvent) -> void: @@ -70,3 +72,7 @@ func _input(event: InputEvent) -> void: elif camera.rotation.x <= -1.6: camera.rotation.x = -1.6 rotate(Vector3.DOWN, camera_rotation.x) + +# this way we can check for the player. +func playerstub() -> void: + pass