Quick answer: Confirm the NavigationRegion3D has MeshInstance3D children with non-empty meshes. If using SOURCE_GEOMETRY_GROUPS_* mode, add the geometry to the named group via the Group panel.

You add a NavigationRegion3D under your level’s terrain and click Bake NavigationMesh. The result: empty — no walkable polygon visible in the gizmo. NavMeshAgents have nowhere to walk. The terrain is clearly there but the baker didn’t see it.

Source Geometry Modes

NavigationMesh’s geometry_source_geometry_mode property controls discovery:

Modes that reference a group require setting geometry_source_group_name to a non-empty string and adding the geometry to that group.

The Fix

For most projects, the simplest approach: parent your terrain meshes under the NavigationRegion3D and use ROOT_NODE_CHILDREN mode:

NavigationRegion3D (geometry_source_geometry_mode = ROOT_NODE_CHILDREN)
  Terrain (MeshInstance3D)
  Building1 (MeshInstance3D)
  Building2 (MeshInstance3D)

Click Bake NavigationMesh in the Inspector. The polygon should fill the walkable area.

Group-Based Mode for Scattered Geometry

If your geometry is scattered throughout the scene tree (not under the NavigationRegion3D):

  1. Set geometry_source_geometry_mode = SOURCE_GEOMETRY_GROUPS_WITH_CHILDREN.
  2. Set geometry_source_group_name = "navmesh_source".
  3. Add every relevant MeshInstance3D to the “navmesh_source” group via the Groups panel.
  4. Bake.

Group-based mode lets you bake nav from geometry that lives anywhere in the scene without restructuring.

Verify Meshes Have AABBs

An empty Mesh resource (loaded but with zero vertices) produces zero AABB and contributes nothing to the bake. Inspect each source MeshInstance3D:

var aabb = mesh_instance.get_aabb()
print("%s aabb size: %s" % [mesh_instance.name, aabb.size])

If size is (0, 0, 0), the mesh is empty. Re-import or reassign a valid Mesh.

Visualize During Bake

Toggle Debug → Visible Navigation. After bake, the walkable area highlights in cyan. If you see no cyan, source geometry isn’t being detected.

Runtime Re-Bake

For destructible terrain:

func on_terrain_destroyed():
    nav_region.bake_navigation_mesh(true)   # on_thread

The bake runs on a worker thread; agents continue using the previous mesh until the new one finishes — no frame stalls.

Verifying

Bake produces a non-empty NavigationMesh. NavMeshAgents can plot paths across the terrain. Move an agent to a far corner; it should walk there following the baked mesh. Empty mesh = agent fails immediately with “Cannot find path”.

“Empty bakes mean the source mode missed the geometry. Parent meshes under the region or group them explicitly.”

For procedural levels, always use a named group. Lets you bake from geometry generated anywhere without reparenting at runtime.