Navigation workflow in 3d levels

Godot version

Godot 4.3

Question

I want to develop a simple 3d dungeon crawler creating a simple 3d level with blockbench. The level is typically made by corridors with floor, walls and ceiling.

I couldn’t figure a viable workflow for creating the navigation, neither in general neither specifically for Godot.

Basically, if you model everything (visual mesh and nav mesh) outside Godot, you have longer iteration times since mesh must be generated manually and as such is hard to match navigationagent requirements (such as height). If you generate visual mesh outside Godot, in Godot you can bake the navigation mesh for the visual one but it ends up being more complex than it needs to be. From what I understood:

Solution 1. Create the level in blockbench, name the floor entities with “-navmesh” name hint, export in GLTF and import in Godot. In this case Godot creates automatically the navmesh from floor meshes. Advantage: automatic generation of nav mesh using baking; drawbacks: (a) every block (in blockbench I couldn’t find a way to crate polygons) has six faces instead of just one, so navigation mesh is 6 times heavier and enemies can roam on vertical faces ideally. (B) the navigation mesh may not be useful at all due to the fact it’s generated from the floor tiles exactly, so you cannot guarantee margins, or heights and so on which are required by the navigation agent. Due to this last problem, this solution is not viable at all.

Solution 2. Similar to solution 1; but In the external tool you model separately floors (visual meshes) and navigation mesh. Drawback 1B is solved since you control the shape of walkable surface, but you have new drawbacks (C) the shape of the walkable surface is determined externally, so you need to test this walkable path in Godot literally trying it with the navigationAgent. If it gets stuck, you can’t regenerate the navigation mesh with different settings, but you go back to the editor, modify the navigation mesh and then re-export. This solution might be viable but it sounds clunky, slow and prone to error. (D) you need to maintain two meshes (visual and navigation) separately.

Solution 3: you build the visual mesh in an external program. You then import it in Godot and you model the navigation mesh inside Godot, adding a second mesh made by dedicated navigation geometry, using baking. This has the advantage (A) yields good walkable paths. But it has drawbacks (B) if the visual model changes externally, you may need to change again the navigation mesh in Godot to match it. So this creates the possibility for inconsistencies, which may be hard if not impossible to detect or test thoroughly.

What are your solutions to the problem? Are they viable? What is your workflow?

Thank you!

I use solution 2, model the nav mesh separately and export it with “-navmesh”, except I do it in Blender. It works for me but I only do it for one relatively small area.
I have nothing helpful to add, just wanted to bump this thread because I’m interested too :sweat_smile:

1 Like

The solution is to design your source geometry for the baking in a way that it does work well-enough with your bake settings and not fall in the pit thinking a navmesh needs to be precision and layout perfect, it is an abstraction after all.

The last thing you want to do is update your navmesh edges entirely manually every single time for every small change. That is so labourous on top of being a big bug surface … it does not scale at all with project growth.

If you look at the navmesh in most AAA games you would tear your hair out how it looks … but guess what … no one cares as long as it works. Game developers have so many more important things to do than adjusting every single navmesh polygon edge by hand everytime a designer slightly changes the geometry or drops a new item.

2 Likes

Thank you!

So from your comments I get that visual and navigation meshes are completely decoupled, so one could go for solution 2 (design a custom navigation mesh externally, and import it as it is in Godot with -navmesh) or solution 3 (baking a custom navigation mesh in Godot, I guess this can be done using meshinstance primitives).

Thank you!

If you bake in the editor you can use meshinstances, but if you also want to rebake things at runtime use collision shapes. Visuals meshes are not at all query friendly for runtime rebaking and will give major performance issues when you try to bake them at runtime.

2 Likes

That’s a good hint; I guess you are referring to parsed_geometry_type attribute of NavigationRegion3D!

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