Godot Version
4.2.2
Question
I have a 3D scene with a flat plane for the floor and a box for a small wall. I have a player object (just a capsule) and an enemy object (also a capsule). I’ve added a NavigationMesh to the main scene, and I have added a NavigationAgent under the player object and the enemy object. I use the player navigationAgent to enable “walk to clicked location” like in the Diablo games. The enemy is supposed to go to the player’s location, but no matter what I try and do, the navigationAgent path for the enemy never ever updates - it’s stuck at the enemy origin. I realize the documentation says this can happen if you try to access the path before the mesh has synced, so I added in the code to execute on the “map_changed” event, as suggested. Yet nothing. Here is the code for my enemy script - what am I doing wrong?
@onready var navigationAgent:NavigationAgent3D = $NavigationAgent3D
@onready var player = $"../Player" as CharacterBody3D
var movement_speed: float = 2.0
var movement_target_position: Vector3 = Vector3(-3.0,0.0,2.0)
var next_path_position: Vector3
# Get the gravity from the project settings to be synced with RigidBody nodes.
var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")
func _ready():
#navigationAgent.path_desired_distance = 0.5
#navigationAgent.target_desired_distance = 0.5
set_physics_process(false)
call_deferred("actor_setup")
print("Ready!")
func actor_setup():
# Wait for the first physics frame so the NavigationServer can sync.
NavigationServer3D.map_changed.connect(Callable(map_ready))
# Now that the navigation map is no longer empty, set the movement target.
#set_movement_target(player.global_transform.origin)
func map_ready(rid):
next_path_position = navigationAgent.get_next_path_position()
print("Next path position A", next_path_position)
set_physics_process(true)
NavigationServer3D.map_changed.disconnect(Callable(map_ready))
func set_movement_target(movement_target:Vector3):
navigationAgent.set_target_position(movement_target)
func _physics_process(delta):
set_movement_target(player.global_transform.origin)
if navigationAgent.is_navigation_finished():
print("It thinks its finished")
return
next_path_position = navigationAgent.get_next_path_position()
print("Enemy Origin ", global_transform.origin)
print("Target Location ", navigationAgent.target_position)
velocity = global_position.direction_to(next_path_position) * movement_speed
move_and_slide()
func _on_navigation_agent_3d_target_reached():
pass
func _on_navigation_agent_3d_path_changed():
print("Next path position B", next_path_position)