I need help changing the position an object wanders to

Godot 4.5 `

I need help having my enemy switch to a random position after they reach their destination, but nothing I do works. I tried watching a few tutorials, but I still couldn’t get it to work. Here is the code of what I’m trying to use.

var nodes: Marker3D = null
var arr = [0,1,2,3,4,5,6,7]
var randarr = randi_range(0,7)

func _ready() → void:
nodes = get_tree().get_nodes_in_group(“Enemy Node”)[randarr]
player = get_tree().get_nodes_in_group(“Player”)[0]

func physics_process(delta: float):
var next_position: Vector3 = enemy.navigation_agent.get_next_path_position()
var NavTarget: Vector3 = enemy.navigation_agent.target_position
NavTarget = nodes.position
enemy.velocity = enemy.global_position.direction_to(next_position) * enemy.MoveSpeedWalk
if nodes.position == enemy.position:
randarr = randi_range(0, 7)
if enemy.navigation_agent.is_navigation_finished():
return

It’s pretty hard to give advise, because it seems like you didn’t share the full code and for most of your variables it is unclear what they are (supposed to be) doing. Assuming this would be the full code:

  • randarr is only used inside the ready function, so changing it later doesn’t do anything. nodes is only getting set in the _ready() function, so it will always stay the same.
  • NavTarget is initialized with the NavigationAgent’s target position, just to overwrite its value with nodes’ position but never using it.
  • return at the end of a function is pointless, thus there’s no reason to check if the navigation is finished for this. (Instead of return, you should change the target position on this condition.)
  • You are never changing enemy.navigation_agent.target_position, which would be necessary to make the enemy move towards a new position. It is also unclear if the target_position has an initial value and what random position you want him to wander to. (Is the group “Enemy Node” a list of positions to randomly choose from?)
  • Neither enemy nor player are defined in the code you shared, player is also never used for anything.
  • I’m also confused about the function name physics_process(), because the virtual function’s name is _physics_process(). Are you manually calling it from elsewhere or is it a typo?
  • Checking if float values are equal (including vectors like positon) should be done via is_equal_approx(). nodes.position == enemy.position will probably never result in true.

Assuming none of the variables would be used elsewhere, the current physics_process() would be the same as:

func physics_process(delta: float):
	var next_position: Vector3 = enemy.navigation_agent.get_next_path_position()
	enemy.velocity = enemy.global_position.direction_to(next_position) * enemy.MoveSpeedWalk

And you would need to add something like:

func physics_process(delta: float):

	if enemy.navigation_agent.is_navigation_finished():
		var new_target_position: Vector3
		# inlcude code here to set new_target_position to a random position
		enemy.navigation_agent.target_position = new_target_position

	var next_position: Vector3 = enemy.navigation_agent.get_next_path_position()
	enemy.velocity = enemy.global_position.direction_to(next_position) * enemy.MoveSpeedWalk
1 Like

Thanks so much! I tried replacing the return condition before but nothing happened. I probably should have assumed that adding the nodes variable wouldn’t do anything when calling for it in process, but I just didn’t think about that. Thanks again!