Struggling to use Navigation nodes (3D)

Godot Version

4.3

Question

This is my first time trying to use any of the navigation components provided by Godot, and I am struggling to get agents not to walk through eachother.

I tried adding NavigationObstacle3D’s that follow units around as they move, but that didn’t seem to have any effect, so I thought maybe I needed to bake the mesh.

After baking, it doesn’t look like it exists anymore in the debug overlay, and the agents stop moving. The NavigationMesh was created by calling create_from_mesh() on a subdivided PlaneMesh. I’m starting to think this was definitely not what I wanted.

Does anyone have advice for how to use the navigation components so that agents using the NavigationRegion3D won’t walk through eachother?

can we see a picture?

sounds like they are following each others positions but don’t have a stopping distance, which you need. can we see some code?

you need your units to either have no collisions between them (set this in collision layers of each character node), or stop at a certain distance, given by the radius of their collision boxes, and the radius of the other.
I believe godot’s navigation can do obstacle avoidance, but this has to be configured in the navmesh.

It’s a bit spaghetti at the moment, so I apologize in advance.

This is the code for setting the next position of the unit using the agent node’s pathfinding.

	navigation_agent.max_speed = movement_speed
	owner.global_position += owner.global_position.direction_to( navigation_agent.get_next_path_position()) * movement_speed * delta

Each unit also has an obstacle that follows them around; the create_builtin function just makes a new <first argument> and adds it as a child of <third argument>.
Edit: There is also a small bit of code in the process function that updates it so that the global position of this navigation component matches that of the unit.

	navigation_component = Factory.create_builtin(NavigationObstacle3D, "NavigationObstacle" + name, Utilities.get_main().terrain.navigation_component)
	navigation_component.set_navigation_map(Utilities.get_main().terrain.navigation_component.get_navigation_map())
	navigation_component.radius = 1.25
	navigation_component.height = 2
	navigation_component.avoidance_enabled = true
	navigation_component.use_3d_avoidance = true
	navigation_component.affect_navigation_mesh = true

These are the parts from Terrain for the NavigationRegion3D child node.

	var mesh = PlaneMesh.new()
	mesh.set_size(Vector2(width, height))
	mesh.subdivide_depth = 30
	mesh.subdivide_width = 30
	navigation_region = Factory.create_builtin(NavigationRegion3D, "NavigationRegion", self)
	var nav_mesh = NavigationMesh.new()
	nav_mesh.create_from_mesh(mesh)
	navigation_region.navigation_mesh = nav_mesh
	#navigation_region.bake_navigation_mesh() # <- Edit: This was making the NavigationRegion3D disappear in the debug overlay. 
	navigation_region.enabled = true

( Before trying to add pathfinding, I was just using a CharacterBody3D as a child of each unit and then moving them towards the destination if there were no collisions. )

Forgot to add the navigation agent creation part:

	navigation_agent = Factory.create_builtin(NavigationAgent3D, "NavigationAgent",  self)
	navigation_agent.avoidance_enabled = true
	navigation_agent.radius = 1.25
	navigation_agent.set_navigation_map(Utilities.get_main().terrain.navigation_component.get_navigation_map())

I’m sorry, I can’t help you with random fragments of code with no context.

We need to look at the ifs and elses, at the code that runs in process/physics_process or ready, WHERE the code is executed.

and from what you tell, this seems to be a very convoluted system that mixes different nodes that might not be designed to work the way you are using them.

godot does not have components. it has nodes. call things by what they are so we are not confused.

you are changing global_position. what are your units?
usually we use CharacterBody3D, in that case you have to set a velocity and call move_and_slide.
with other physics bodies we also call their movement methods like apply_force.
we never change position manually.

make a scene with all these things set and spawn it.
the method you are using is overly complicated for no reason.
also, again, nodes have to be inside the tree to work, you never call add_child or add_sibling, maybe you do in that factory singleton, but you didn’t post that part so it’s just speculation.

CharacterBody3D should never be child of other physics objects, and vice-versa. that causes physics bugs and problems.

the way a tree should look like is:


NavigationRegion3D
  |-> Character
         |-> Agent
  |-> Character
         |-> Agent
  |-> obstacles

etc. do not nest agents or obstacles.

Thank you for the insight!

I will mark this as resolved since you have given me valuable information to work off of and, as you mentioned, the code fragments I supplied are random and not very well-thought out.

Thank you for your time and for the help! :slight_smile:

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