feat: add npc path finding to the zones based on needs
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
[gd_scene load_steps=12 format=3 uid="uid://rs3hv73svbpa"]
|
[gd_scene load_steps=13 format=3 uid="uid://rs3hv73svbpa"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://4mg67crlim53" path="res://player/player.gd" id="1_h2yge"]
|
[ext_resource type="Script" uid="uid://4mg67crlim53" path="res://player/player.gd" id="1_h2yge"]
|
||||||
[ext_resource type="Script" uid="uid://ii8ai801jur2" path="res://player/camera_rig.gd" id="2_1bvp3"]
|
[ext_resource type="Script" uid="uid://ii8ai801jur2" path="res://player/camera_rig.gd" id="2_1bvp3"]
|
||||||
@@ -6,6 +6,10 @@
|
|||||||
[ext_resource type="Script" uid="uid://c1f3b26n4yntf" path="res://world/world_view_manager.gd" id="4_1bvp3"]
|
[ext_resource type="Script" uid="uid://c1f3b26n4yntf" path="res://world/world_view_manager.gd" id="4_1bvp3"]
|
||||||
[ext_resource type="PackedScene" uid="uid://dhxxyprqflotq" path="res://player/npc/NpcVisual.tscn" id="5_lquwl"]
|
[ext_resource type="PackedScene" uid="uid://dhxxyprqflotq" path="res://player/npc/NpcVisual.tscn" id="5_lquwl"]
|
||||||
|
|
||||||
|
[sub_resource type="NavigationMesh" id="NavigationMesh_lquwl"]
|
||||||
|
vertices = PackedVector3Array(-14.5, 0.4, -14.5, -14.5, 0.4, 14.5, 14.5, 0.4, 14.5, 14.5, 0.4, -14.5)
|
||||||
|
polygons = [PackedInt32Array(3, 2, 0), PackedInt32Array(0, 2, 1)]
|
||||||
|
|
||||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_o5qli"]
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_o5qli"]
|
||||||
albedo_color = Color(0.16862746, 0.52156866, 0.30588236, 1)
|
albedo_color = Color(0.16862746, 0.52156866, 0.30588236, 1)
|
||||||
|
|
||||||
@@ -34,10 +38,14 @@ light_energy = 2.0
|
|||||||
|
|
||||||
[node name="World" type="Node3D" parent="."]
|
[node name="World" type="Node3D" parent="."]
|
||||||
|
|
||||||
[node name="Ground" type="MeshInstance3D" parent="World"]
|
[node name="NavigationRegion3D" type="NavigationRegion3D" parent="World"]
|
||||||
|
navigation_mesh = SubResource("NavigationMesh_lquwl")
|
||||||
|
|
||||||
|
[node name="Ground" type="MeshInstance3D" parent="World/NavigationRegion3D"]
|
||||||
transform = Transform3D(30, 0, 0, 0, 0.1, 0, 0, 0, 30, 0, -0.05, 0)
|
transform = Transform3D(30, 0, 0, 0, 0.1, 0, 0, 0, 30, 0, -0.05, 0)
|
||||||
material_override = SubResource("StandardMaterial3D_o5qli")
|
material_override = SubResource("StandardMaterial3D_o5qli")
|
||||||
mesh = SubResource("BoxMesh_sgp6g")
|
mesh = SubResource("BoxMesh_sgp6g")
|
||||||
|
skeleton = NodePath("../..")
|
||||||
|
|
||||||
[node name="Player" type="CharacterBody3D" parent="." node_paths=PackedStringArray("camera_rig")]
|
[node name="Player" type="CharacterBody3D" parent="." node_paths=PackedStringArray("camera_rig")]
|
||||||
script = ExtResource("1_h2yge")
|
script = ExtResource("1_h2yge")
|
||||||
|
|||||||
+42
-13
@@ -1,41 +1,70 @@
|
|||||||
extends CharacterBody3D
|
extends CharacterBody3D
|
||||||
|
|
||||||
|
const DEBUG_LOGS := false
|
||||||
|
|
||||||
@export var move_speed := 3.0
|
@export var move_speed := 3.0
|
||||||
@export var rotation_speed := 8.0
|
@export var rotation_speed := 8.0
|
||||||
|
@export var waypoint_reached_distance := 0.35
|
||||||
|
|
||||||
|
@onready var nav_agent: NavigationAgent3D = $NavigationAgent3D
|
||||||
|
|
||||||
var sim_id: int = -1
|
var sim_id: int = -1
|
||||||
var npc_name: String = ""
|
var npc_name: String = ""
|
||||||
var profession: String = ""
|
var profession: String = ""
|
||||||
var target_position: Vector3
|
|
||||||
var has_target := false
|
var current_path: PackedVector3Array = []
|
||||||
|
var path_index := 0
|
||||||
|
var current_target := Vector3.INF
|
||||||
|
|
||||||
|
func debug_log(message: String) -> void:
|
||||||
|
if DEBUG_LOGS:
|
||||||
|
print("[NPCVisual] ", name, " | ", message)
|
||||||
|
|
||||||
func setup_from_sim(npc: SimNPC) -> void:
|
func setup_from_sim(npc: SimNPC) -> void:
|
||||||
sim_id = npc.id
|
sim_id = npc.id
|
||||||
npc_name = npc.npc_name
|
npc_name = npc.npc_name
|
||||||
profession = npc.profession
|
profession = npc.profession
|
||||||
name = "NPC_%s_%s" % [sim_id, npc_name]
|
name = "NPC_%s_%s" % [sim_id, npc_name]
|
||||||
target_position = global_position
|
|
||||||
|
|
||||||
func set_target_position(pos: Vector3) -> void:
|
func set_target_position(pos: Vector3) -> void:
|
||||||
target_position = pos
|
if current_target.distance_to(pos) < 0.1:
|
||||||
has_target = true
|
|
||||||
|
|
||||||
func _physics_process(delta: float) -> void:
|
|
||||||
if not has_target:
|
|
||||||
return
|
return
|
||||||
|
|
||||||
var to_target := target_position - global_position
|
current_target = pos
|
||||||
to_target.y = 0
|
nav_agent.target_position = pos
|
||||||
|
|
||||||
if to_target.length() < 0.25:
|
await get_tree().physics_frame
|
||||||
|
|
||||||
|
current_path = NavigationServer3D.map_get_path(
|
||||||
|
get_world_3d().navigation_map,
|
||||||
|
global_position,
|
||||||
|
pos,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
|
||||||
|
path_index = 0
|
||||||
|
|
||||||
|
debug_log("New target: %s Path points: %s" % [pos, current_path.size()])
|
||||||
|
|
||||||
|
func _physics_process(delta: float) -> void:
|
||||||
|
if current_path.is_empty() or path_index >= current_path.size():
|
||||||
velocity = Vector3.ZERO
|
velocity = Vector3.ZERO
|
||||||
move_and_slide()
|
move_and_slide()
|
||||||
return
|
return
|
||||||
|
|
||||||
var direction := to_target.normalized()
|
var next_pos := current_path[path_index]
|
||||||
|
var flat_next_pos := Vector3(next_pos.x, global_position.y, next_pos.z)
|
||||||
|
var to_next := flat_next_pos - global_position
|
||||||
|
|
||||||
|
if to_next.length() <= waypoint_reached_distance:
|
||||||
|
path_index += 1
|
||||||
|
return
|
||||||
|
|
||||||
|
var direction := to_next.normalized()
|
||||||
|
|
||||||
velocity.x = direction.x * move_speed
|
velocity.x = direction.x * move_speed
|
||||||
velocity.z = direction.z * move_speed
|
velocity.z = direction.z * move_speed
|
||||||
velocity.y = 0
|
velocity.y = 0.0
|
||||||
|
|
||||||
move_and_slide()
|
move_and_slide()
|
||||||
|
|
||||||
|
|||||||
@@ -26,3 +26,9 @@ mesh = SubResource("CapsuleMesh_d844k")
|
|||||||
[node name="FaceMarker" type="MeshInstance3D" parent="."]
|
[node name="FaceMarker" type="MeshInstance3D" parent="."]
|
||||||
transform = Transform3D(0.15, 0, 0, 0, 0.15, 0, 0, 0, 0.35, 0, 1.2, 0.59052056)
|
transform = Transform3D(0.15, 0, 0, 0, 0.15, 0, 0, 0, 0.35, 0, 1.2, 0.59052056)
|
||||||
mesh = SubResource("BoxMesh_d844k")
|
mesh = SubResource("BoxMesh_d844k")
|
||||||
|
|
||||||
|
[node name="NavigationAgent3D" type="NavigationAgent3D" parent="."]
|
||||||
|
path_desired_distance = 0.3
|
||||||
|
target_desired_distance = 0.5
|
||||||
|
height = 1.7
|
||||||
|
radius = 0.4
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
extends Node
|
extends Node
|
||||||
|
|
||||||
|
const DEBUG_LOGS := true
|
||||||
|
|
||||||
@export var npc_visual_scene: PackedScene
|
@export var npc_visual_scene: PackedScene
|
||||||
@export var simulation_manager: Node
|
@export var simulation_manager: Node
|
||||||
@export var active_npcs_parent: Node3D
|
@export var active_npcs_parent: Node3D
|
||||||
@@ -11,11 +13,24 @@ extends Node
|
|||||||
@export var rest_zone: Marker3D
|
@export var rest_zone: Marker3D
|
||||||
@export var food_zone: Marker3D
|
@export var food_zone: Marker3D
|
||||||
|
|
||||||
var active_npc_visuals := {} # sim_id -> NPCVisual
|
var active_npc_visuals := {}
|
||||||
|
|
||||||
|
func debug_log(message: String) -> void:
|
||||||
|
if DEBUG_LOGS:
|
||||||
|
print("[WorldViewManager] ", message)
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
call_deferred("spawn_initial_npcs")
|
call_deferred("spawn_initial_npcs")
|
||||||
|
|
||||||
|
var target_update_timer := 0.0
|
||||||
|
var target_update_interval := 0.5
|
||||||
|
|
||||||
|
func _process(delta: float) -> void:
|
||||||
|
target_update_timer += delta
|
||||||
|
if target_update_timer >= target_update_interval:
|
||||||
|
target_update_timer = 0.0
|
||||||
|
update_npc_targets()
|
||||||
|
|
||||||
func spawn_initial_npcs() -> void:
|
func spawn_initial_npcs() -> void:
|
||||||
if simulation_manager == null:
|
if simulation_manager == null:
|
||||||
push_error("WorldViewManager: simulation_manager is missing")
|
push_error("WorldViewManager: simulation_manager is missing")
|
||||||
@@ -25,6 +40,12 @@ func spawn_initial_npcs() -> void:
|
|||||||
push_error("WorldViewManager: npc_visual_scene is missing")
|
push_error("WorldViewManager: npc_visual_scene is missing")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if active_npcs_parent == null:
|
||||||
|
push_error("WorldViewManager: active_npcs_parent is missing")
|
||||||
|
return
|
||||||
|
|
||||||
|
debug_log("Spawning NPC visuals. Count: %s" % simulation_manager.npcs.size())
|
||||||
|
|
||||||
for npc in simulation_manager.npcs:
|
for npc in simulation_manager.npcs:
|
||||||
spawn_npc_visual(npc)
|
spawn_npc_visual(npc)
|
||||||
|
|
||||||
@@ -32,7 +53,7 @@ func spawn_npc_visual(npc: SimNPC) -> void:
|
|||||||
if active_npc_visuals.has(npc.id):
|
if active_npc_visuals.has(npc.id):
|
||||||
return
|
return
|
||||||
|
|
||||||
var visual := npc_visual_scene.instantiate()
|
var visual = npc_visual_scene.instantiate()
|
||||||
active_npcs_parent.add_child(visual)
|
active_npcs_parent.add_child(visual)
|
||||||
|
|
||||||
visual.global_position = npc.position
|
visual.global_position = npc.position
|
||||||
@@ -40,10 +61,8 @@ func spawn_npc_visual(npc: SimNPC) -> void:
|
|||||||
|
|
||||||
active_npc_visuals[npc.id] = visual
|
active_npc_visuals[npc.id] = visual
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
debug_log("Spawned visual for %s at %s" % [npc.npc_name, npc.position])
|
||||||
update_npc_targets()
|
|
||||||
|
|
||||||
|
|
||||||
func update_npc_targets() -> void:
|
func update_npc_targets() -> void:
|
||||||
if simulation_manager == null:
|
if simulation_manager == null:
|
||||||
return
|
return
|
||||||
@@ -55,8 +74,11 @@ func update_npc_targets() -> void:
|
|||||||
var visual = active_npc_visuals[npc.id]
|
var visual = active_npc_visuals[npc.id]
|
||||||
var target := get_target_for_task(npc.current_task)
|
var target := get_target_for_task(npc.current_task)
|
||||||
|
|
||||||
if target != null:
|
if target == null:
|
||||||
visual.set_target_position(target.global_position)
|
debug_log("No target for task: %s" % npc.current_task)
|
||||||
|
continue
|
||||||
|
|
||||||
|
visual.set_target_position(target.global_position)
|
||||||
|
|
||||||
func get_target_for_task(task: String) -> Marker3D:
|
func get_target_for_task(task: String) -> Marker3D:
|
||||||
match task:
|
match task:
|
||||||
|
|||||||
Reference in New Issue
Block a user