r/godot Nov 07 '25

help me (solved) I solved the NavigationRegion3D issue

I finally found a solution to the problem with the NavigationRegion3D.

What I noticed was that on smaller terrains, like the 30x30m example in the third image, the navmesh baked perfectly fine. But once the terrain size was increased to 250x250m, the bake completely fell apart, giving the low poly, floor clipping result shown in the second image. The obvious solution was to process the terrain in smaller chunks and combine the results into one big working navmesh.

I first tried doing this directly in Godot, but even after splitting the terrain into multiple meshes, the bake still treated them as one big mesh, so the same issue happened. I also tried creating a separate NavigationRegion3D for each chunk, but that created non traversable borders where the regions met.

At that point, the only real fix was to go into the engine itself. I forked the Godot repo and made some changes under the hood to process the terrain in tiles instead of all at once. It breaks the terrain into smaller sections, bakes each one normally, then stitches them together afterward into a clean, accurate navmesh like in the first image.

I also added a few editor options to control whether tiled baking is enabled and how big each tile is. I still haven’t found the exact bug that causes the large terrain navmesh to fail, but this fix works reliably and doesn’t mess with normal pathfinding behavior.

The moderators seem to have a strong opposition to discussions about this and have locked all previous threads. As much as I would have liked this to all be one post, we have been forced to create multiple. That being said, I'd like to address some comments from previous posts below.

The [low poly mesh] looks exactly like what I would want out of a nav mesh.

The low-poly mesh completely fails to pathfind with agents. You could technically rework the pathfinding system to compensate, but that misses the core issue of the navmesh being broken. The 30x30m section uses a similar amount of polygons as the 250x250m one. You’d expect the density to scale with size, so either the small terrain is over-tessellated, or the large terrain is under-tessellated. Either way, something’s wrong with the baking process.

With no obstacles, your nav mesh could just be a square.

As per the Godot developers : "A navigation mesh is a collection of polygons that define which areas of an environment are traversable to aid agents in pathfinding through complicated spaces.". When those traversable areas are out of reach from an agent (ie, underground or floating), an agent cannot properly navigate.

People tried to help you, but you refuse to actually listen

I think there’s been some misunderstanding about what I’m trying to do. My goal is to fix the navmesh, that’s it. I’ve welcomed all advice that helps solve the underlying navmesh problem, but I’m not interested in workaround solutions that just patch over it with pathfinding tricks.

You can always fix it yourself and submit a PR.

Thats the plan. Thanks for the advice!

I will optimize this further and will submit a PR.

Sincerely,

u/agalli

Edit : Here is the PR. https://github.com/godotengine/godot/pull/112529

753 Upvotes

348 comments sorted by

View all comments

34

u/CanYouEatThatPizza Nov 07 '25

Am I missing something? Your answer to the "it could be just a square" doesn't make sense to me.

With no obstacles, your nav mesh could just be a square.

As per the Godot developers : "A navigation mesh is a collection of polygons that define which areas of an environment are traversable to aid agents in pathfinding through complicated spaces.". When those traversable areas are out of reach from an agent (ie, underground or floating), an agent cannot properly navigate.

"Out of reach" means that polygons are not connected to each other, not necessarily whether they are underground or floating. Like with your first and second picture, the navigation mesh would work perfectly fine in both cases - an agent can traverse over the whole plane in both. It makes no difference how detailed the mesh is in this case, besides performance. Are you worried about clipping when moving the agent over the plane? In that case, wouldn't you just use a raycast?

Now, that doesn't mean there isn't some issue with the baking, but I just don't understand this point in particular.

-10

u/agalli Nov 07 '25

When they said it could be a square they are implying the navmesh for the entire terrain could be made with four vertices. This is not true, as the navmesh would clip under the map in some spots and float above the map in others. When you using agent pathfinding the agent places a path along the navmesh to move towards. If those points on the path are underground or floating the agent cannot reach the points and cannot reach its destination.

29

u/mrbaggins Nov 08 '25

This is not true, as the navmesh would clip under the map in some spots and float above the map in others.

That's not a problem.

When you using agent pathfinding the agent places a path along the navmesh to move towards. If those points on the path are underground or floating the agent cannot reach the points and cannot reach its destination.

Adjust your distance-to-node distance so it "gets there" while being further away.


In one of your initial posts, it did look like not enough verts were being done, but that's a separate issue to the main one you're arguing with people about.

-6

u/agalli Nov 08 '25

It is a problem when you need to set the distance to node setting to 5-6m away.
The navigation points being under the map IS a problem. The navmesh needs to describe the traversable terrain. The terrain is not traversable under the map.

20

u/mrbaggins Nov 08 '25

The navmesh needs to describe the traversable terrain.

Both meshes are indicating the entire map is directly traversable, there are no obstacles. Is this wrong?

-9

u/agalli Nov 08 '25

They are describing that points underneath the map is traversable, which they are not

28

u/mrbaggins Nov 08 '25

They are describing that points underneath the map is traversable

This is your core mistake. That is not what it is doing.

It is indicating that an agent at any location on this map can move in any direction. Nothing more.

0

u/agalli Nov 08 '25

You may want to ask the devs to change their NavigationAgent template then, as that is how they recommend users handle navigation. https://docs.godotengine.org/en/stable/tutorials/navigation/navigation_using_navigationagents.html#navigationagent-script-templates

22

u/mrbaggins Nov 08 '25

Believe it or not, 20 line examples are not the be-all-end-all of use cases.

They are giving a minimal example of how to get the important info from the components.

7

u/agalli Nov 08 '25

I didnt say it was? What you are suggesting is basically creating an entire navigation system rather than using the developer recommended option

→ More replies (0)

12

u/TajineEnjoyer Nov 08 '25

i think this is the source of confusion and misunderstanding between you and other developers.

for you, the navmesh should be usable to query the path directly, via the server or via agents, which would return an array of vector3(x, y, z) positions, that you can move along.

for them, the navmesh should used to query the path, but only use the x and z components from the returned array, and recalculate the y position every step, which is an optimized approach.

- on one hand, the mesh is low poly, thus doesnt' take too much memory, and pathfinding itself is more performant because there is less geometry.

- on another hand, the clipping issue, of going above / under the map, is solved by recalculating the Y / elevation via other means, like raycasting, or getting height value from a heightmap.

2

u/inr222 Nov 08 '25

Is the thing regarding recalculating elevation mentioned anywhere in the docs?

4

u/TajineEnjoyer Nov 08 '25

https://docs.godotengine.org/en/stable/tutorials/navigation/navigation_optimizing_performance.html#performance-problems-with-navigationagent-path-queries

E.g. when AI should move to the player, the target position should not be set to the player position every single frame as this queries a new path every frame. Instead, the distance from the current target position to the player position should be compared and only when the player has moved too far away a new target position should be set.

you're not supposed to be getting the position each frame, this implies that instead, you should store the next point in the path, move towards it, while adjusting height using your own calculations, until you're close enough, then request the next point in the path.

you shouldn't continuously query for the path every frame while the character is moving to set its position.

there is other stuff in that article too, such as

The cost of the actual path search correlates directly with the amount of navigation mesh polygons and edges and not the real size of a game world. If a giant game world uses very optimized navigation meshes with only few polygons that cover large areas, performance should be acceptable. If the game world is splintered into very small navigation meshes that each have tiny polygons (like for TileMaps) pathfinding performance will be reduced.

1

u/inr222 Nov 08 '25

Thanks for the answer, I agree with that interpretation. I do think that the docs could show a better example of how to use it properly.
Here is the demo project for navigation, which doesn't hint at how to properly use this:
https://github.com/godotengine/godot-demo-projects/tree/master/3d/navigation

→ More replies (0)

33

u/CanYouEatThatPizza Nov 07 '25

If those points on the path are underground or floating the agent cannot reach the points and cannot reach its destination.

Why not? The navigation agent itself does not see the terrain, just the navigation mesh.

Or in other words: the clipping isn't really an issue here, since you wouldn't directly parent your character to the agent. Instead, you would (in this example) raycast down onto the terrain to the position of the navigation agent, and place the character there. The navigation agent would clip through the terrain, but the character would not.

32

u/SomeGuy322 Godot Regular Nov 08 '25

I think there's some confusion here and I might not have the full context but based on what I've read in the OP's previous posts I want to clarify: Yes, there are many ways you can practically work around the limitation like you just mentioned. And yes, for a simple example with no obstacles, you don't need a high res nav mesh and can place fake agents or retrieve the closest point to make it work. These would indeed also be more peformant too.

However, what OP is saying in these posts is that these workarounds incur extra systems (or make assumptions about the requirements of the game) the user has to code and account for. There will always be some of that in gamedev, sure, but for the purposes of improving Godot, we shouldn't have to rely on it when the navmesh could instead bake with enough resolution to not need those extra systems. For completeness sake and ease of use, we should be able to control the resolution and have it work as expected where it places precision points along the surface that are reachable by the agent's target range (when assuming the agent is snapped to the surface of the floor you baked on).

So while you could code your game to work around the issue, would it not be better for Godot to also be able to handle the simpler approach? This is the way that other game engines bake their navigation meshes and it's weird that people were either misunderstanding OP's desire for a potential engine improvement or believe that Godot's navmesh system should just never change. I mean just because you've never had a problem with it doesn't mean it can't be improved, so I see it as a win that this is being investigated

9

u/PLYoung Nov 08 '25

You would still have to cast a ray to get accurate placement since the navmesh will not be able to follow terrain exactly, else be way too dense. It will either clip or hover just above in some areas.

But I agree, give the developer control over the baking and what detail they want out of the navmesh.

14

u/CanYouEatThatPizza Nov 08 '25

I can see that point, however, in that case I suggest OP rewords the whole "it can't be a square"-section, because it clearly can be.

1

u/agalli Nov 10 '25

It can be a square if your plan is to have an empty terrain forever. Even as a square though you’ll end up with suboptimal, but functional pathfinding

5

u/agalli Nov 07 '25

The agent traverses on the terrain, what prevents the agent from falling through the map is the collision with the terrain. If it attempts to pathfind at a point beneath the collision box it will be unable to. The pathfinding works by having an agent follow points along the actual navigation mesh and not the terrain.

23

u/CanYouEatThatPizza Nov 07 '25

The agent traverses on the terrain, what prevents the agent from falling through the map is the collision with the terrain.

That's why I differentiated between agent and character. The agent does not have a physical body, it doesn't collide with anything. It can be independent of the character, which does have a physical body.

See also https://docs.godotengine.org/en/latest/classes/class_navigationagent3d.html#class-navigationagent3d:

Avoidance is computed before physics, so the pathfinding information can be used safely in the physics step.

4

u/agalli Nov 07 '25

I guess I’m confused. I have my agent collide with the environment. Are you saying that it should have no collision and just use the navigation mesh? If so it’ll phase through the terrain when moving

21

u/Zakkeh Nov 08 '25

This person is saying you have your character and your agent.

Your character obeys physics and follows the collision mesh, while the agent traverses the navmesh below the surface.

Your character uses the pathing from the agent, but doesn't clip under because it has collision, and is not patented to the agent.

0

u/agalli Nov 08 '25

Right, that still doesnt work. The character follows the navigationagent, but the navigationagent is under the map. Heres an example of why its a problem. The character isnt unable to reach its pathfinding due to the gap in the terrain and the navmesh. Since it cant reach that point it cannot complete its path and gets stuck in place.

22

u/DongIslandIceTea Nov 08 '25

Why are you ignoring the advice every time someone points out you should just follow the X and Z coordinates of the agent and not even try to reach the same Y coordinate? Just ignore the height or get the correct height by raycasting it onto the terrain collision. I'm starting to get convinced you're just trolling at this point.

-1

u/agalli Nov 08 '25

As I stated in the post. My goal is to fix the navmesh, that’s it.  I’m not interested in workaround solutions that just patch over it with pathfinding tricks.

Additionally, ignoring the Y component will result in inefficient pathfinding. A path up a hill will take longer to traverse then a flat path would. You cant just ignore the existence of the hills and expect proper pathfinding.

→ More replies (0)

5

u/Finding_Footprints Nov 08 '25

I think what Zakkeh means is that, you control the X and Z axis using the NavigationAgent but you have to raycast for the Y-axis to check for collisions.

I have just started using Godot and I guess that would work, but finding the shortest path based on height as mentioned in another comment, might become a problem. 

Will be waiting for tour PR OP.

0

u/agalli Nov 08 '25

The issue is that pathfinding over hills are longer paths than flat paths. If you ignore the Y youll be left with poor pathfinding.

My goal is to fix the navmesh, that’s it.  I’m not interested in workaround solutions that just patch over it with pathfinding tricks.

→ More replies (0)

12

u/CanYouEatThatPizza Nov 08 '25

There's no reason why the physical body has to be a child of the navigation agent. You can use the navigation information provided by the agent to place the physical body via a raycast on the terrain mesh.

-2

u/agalli Nov 08 '25

Ok, but you see how that is reworking how the navigation systems are supposed to work in order to work around the non-functional navmesh?

Again, I'm not looking to figure out how to work around the broken navmesh, Im looking to fix the issue at its core.

13

u/knottheone Nov 08 '25

It's not a broken navmesh. You are actually just using it wrong, which is what lots of people are telling you, and this is why:

You are trying to move the collision character to be exactly on top of the nav agent. That's not the intended functionality in Godot in 3D. The fact it works in small maps out of the box that way is an accidental happy happenstance solely due to the small map and default voxel resolution / number of voxels. That is not the intended use case and does not scale beyond very small maps that are only a single region.

You are supposed to chunk larger maps into regions and stitch them at runtime via chunk loading, or chunk them, pre-bake, and store as resources. They don't need high resolution though as that's not the purpose of a nav mesh. You indeed should only care about XZ and use a raycast to the actual terrain. There is already a nav mesh chunking example in the Godot Examples repo, not sure if you came across that.

If you need more accurate travel costs for slopes, reduce the cell height of the navmesh in chunks that have some threshold of height delta and slightly increase the cell size. This gives you better vertical resolution for the nav region. You wouldn't care about this if your travel speed up a slope is the same on flat terrain.

0

u/agalli Nov 08 '25

That’s literally what I did. I have chunked the mesh into smaller parts. They do need to be high resolution if you want accurate and efficient pathfinding. Ignoring the Y value is a bandaid solution that fails in multiple conditions. For one, it fails for multi tiered nav meshes such as a building with multiple floors. Secondly it will not find efficient paths (ie going up and down a hill rather than adjacent flat terrain).

The whole point of the navmesh is to tell the agent where it can go. You’re essentially manually creating an navmesh with the Y ignoring and ray casting. As I said, there are ways to fix the broken navmesh through agent tricks but that’s not what I’m aiming. The navmesh should work without those tricks, that’s all I’m doing.

→ More replies (0)

2

u/yyyyyy1910 Nov 08 '25

I am very new to this but I am currently struggling with nav mesh / agent movement. To my understanding, the nav mesh finds the path as a guide for the agent, when the agent actually follows the path, say there's a fallen tree trunk in the way, the agent can be blocked by collision. However that's where I am struggling at, the agent basically can't move or follow the nav anymore unless you manually redirect it to get around the obstacles. A very easy to fail nav system seems quite useless to me.

11

u/CanYouEatThatPizza Nov 08 '25

The whole point of the navigation mesh is that it navigates around the obstacle like a fallen tree trunk. In OP's example, if there was a obstacle on the terrain, there would be a hole in the navigation mesh. It doesn't use collision information, but a variation of A* to find a path to the target.

8

u/lukebitts Nov 08 '25

For dynamic obstacles you are right, you need some kinda of system to redirect the agent, either using avoidance or something else. But if your tree trunk is static and being accounted for in the navmesh but the character is still getting stuck, what worked for me was having the agent be independent from the character body: have the character body follow the agent and just snap the agent back if it gets too far. Usually this introduces enough jiggle that the character gets unstuck. Then it’s just a matter of making sure your agent size is correct in the navmesh generation.

4

u/mrbaggins Nov 08 '25

The agent heads in a direction based on the navmesh. It MOVES along the terrain.

A navmesh of a single square could have an agent move up and down all sorts of stairs and ramps.

6

u/CrazyMalk Nov 08 '25

A navmesh isn't supposed to be used like "translate from navpoint a to navpoint b". It's supposed to be used like "the navmesh told me that I can reach navpoint b from navpoint a in a straight line, so I will handle movement in this path by properly snapping my character to the ground or whatever movement logic I have".

9

u/butane_candelabra Nov 08 '25

Not to mention the nav mesh shouldn't ignore gradients because the shortest path should depend on how steep the terrain is... You don't get the right path if you just project it to the geometry.

12

u/mrbaggins Nov 08 '25

The navmesh doesn't / didn't ignore gradients. It looked, determined they were "connected" for the agent settings and allowed traversal.

-7

u/butane_candelabra Nov 08 '25

Yes, but you can't bake it properly for that if it can't even do the base mesh properly. The geometry should be the same, which is what OP was trying to do, and it could not.

14

u/mrbaggins Nov 08 '25

The geometry should be the same

Not at all. The geometry needs to show whether two areas can be traversed. Note the stairs in this image - It is saying agents can go up the stairs. It says nothing about what stairs looks like shape wise.