Navigation diagnostics
Find empty-path, connection, and physics mismatch causes.
First identify what failed: the surface, region connections, query result, or physical movement. A navigation overlay does not prove that the character collider fits along the route.
Diagnostic order
- Check that the region contains polygons, belongs to the intended map, and is enabled. A nonzero
MapGetIterationIdmeans an iteration has been published, not that every latest change has finished. - Compare the query map and layer mask with the region. A link also needs matching layers and an allowed direction.
- Read the path and compare both endpoints with the requested start and goal. A nonempty path can be partial; finishing a route does not mean reaching the goal.
- If the path is correct, inspect parent movement: velocity,
MoveAndSlide(), collider, and physics layers. An agent does not move the body itself. - For timing spikes, separate geometry parsing, baking, map updates, path searches, and avoidance. Measurement and optimization.
Debug visualization
In a debug build, NavigationServer2D.SetDebugEnabled(true) and NavigationServer3D.SetDebugEnabled(true) enable server flags. GetDebugEnabled() reads them. This does not create display geometry.
The corresponding Entity types build standard region visualization. Server-only RIDs do not automatically appear on screen. For a custom server-based implementation, draw published-data outlines and the actual query result separately.
Project settings under debug/shapes/navigation control edge lines, surface colors, and connection display. Seeing through geometry helps reveal overlapping surfaces; it does not make a hidden connection traversable. Use visualization for development rather than game logic: the setter implementation is guarded by DEBUG_ENABLED.
Read the counters correctly
| Data | Meaning |
|---|---|
GetProcessInfo(ProcessInfo.ActiveMaps) | Active maps in that 2D or 3D server. |
RegionCount, PolygonCount | Aggregate over active maps after server processing, not every RID ever created. |
Performance.Monitor.NavigationPolygonCount | Sum of 2D and 3D. Use Navigation2DPolygonCount or Navigation3DPolygonCount for one dimension. |
EdgeMergeCount, EdgeConnectionCount, EdgeFreeCount | Information about connection methods and remaining edges. Do not add these as three independent kinds of traversability. |
Performance.Monitor.TimeNavigationProcess | Navigation server processing time in seconds, not the duration of your individual path-search call. |
A disabled region still belongs to its map and remains in RegionCount, although queries cannot traverse it. The counter is not a count of accessible gameplay areas. Deactivating a map removes its contribution from the aggregate; it does not free its RID.
Symptom → next check
| Symptom | Check |
|---|---|
| Empty path immediately after creation | Wait for the intended geometry to publish; check the map, polygons, and nonzero mask. |
| Visible surfaces do not connect | Edge connections: map grid, gap, and connection toggles. |
| A link does not provide passage | Links: direction, attachment radius, layers, and the 1.0.0 IncludedRegions limitation. |
| The agent finished far from the goal | Partial path; compare the endpoint with the original goal and inspect IsTargetReached(). |
| The character hits a wall | Collision and navigation disagree. Physical 3D example. |
| Disabling a region did not reduce its counter | The region remains on an active map; disabling is not removal. |
Counters, 2D/3D sums, and flag switching were executed on installed version 1.0.0. Visible overlays, editor interactions, and a release export were not evaluated by this check.