How do you properly set moving target to navigate to?

Godot Version

4.3

Question

I am trying to create an AI that follows the player. Right now I am coming across an issue that is_navigation_finished is returning true even though a new set_target_position has been set. The debug view shows that once the new target is set a line to show the path is not being created. So somehow the target being set I’m guessing is invalid or there is a race condition.

According to the documentation set_target_position should at least add another path to navigate towards

If set, a new navigation path from the current agent position to the target_position is requested from the NavigationServer.

Here is the code for the enemy:


extends CharacterBody3D
var movement_speed: float = 2.0
var movement_target_position: Vector3 = Vector3(0.0,2.26,4.65)

@onready var navigation_agent: NavigationAgent3D = $NavigationAgent3D
var mapRID : RID
@onready var bt :BTPlayer = $BTPlayer
func _ready():
	# These values need to be adjusted for the actor's speed
	# and the navigation layout.
	navigation_agent.path_desired_distance = 0.5
	navigation_agent.target_desired_distance = 0.5
	bt.blackboard.set_var(&"target", self)
	# Make sure to not await during _ready.
	actor_setup.call_deferred()

func actor_setup():
	# Wait for the first physics frame so the NavigationServer can sync.
	await get_tree().physics_frame
	
	mapRID = navigation_agent.get_navigation_map()
	
	# only is able to move when I call it inside here
	#set_movement_target(movement_target_position)

func set_movement_target(movement_target: Vector3):
	navigation_agent.set_target_position(movement_target)

func _physics_process(delta):
	if navigation_agent.is_navigation_finished():
		print("we are done")
		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
	move_and_slide()

I am setting the new target every 10 secs on the enemy’s state machine like this:

func _tick(delta: float) -> Status:
	var target := blackboard.get_var(target_var) as Node3D
	if not is_instance_valid(target):
		return FAILURE
	print("new target set!")
	agent.set_movement_target(target.position)
	return SUCCESS

What is the correct way to change the target?

I feel really dumb. I set the target to itself so that it was always trying to move to its own position.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.