Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Redot.

Using navigation meshes

../../_images/nav_meshes.webp

2D and 3D versions of the navigation mesh are available as NavigationPolygon and NavigationMesh respectively.

Note

A navigation mesh only describes a traversable area for an agent's center position. Any radius values an agent may have are ignored. If you want pathfinding to account for an agent's (collision) size you need to shrink the navigation mesh accordingly.

Navigation works independently from other engine parts like rendering or physics. Navigation meshes are the only things considered when doing pathfinding, e.g. visuals and collision shapes for example are completely ignored by the navigation system. If you need to take other data (like visuals for example) into account when doing pathfinding, you need to adapt your navigation meshes accordingly. The process of factoring in navigation restrictions in navigation meshes is commonly referred to as navigation mesh baking.

Navigation mesh polygon convex vs concave comparison

A navigation mesh describes a surface that an agent can stand on safely with its center compared to physics shapes that describe outer collision bounds.

If you experience clipping or collision problems while following navigation paths, always remember that you need to tell the navigation system what your intentions are through an appropriate navigation mesh. By itself the navigation system will never know "this is a tree / rock / wall collision shape or visual mesh" because it only knows that "here I was told I can path safely because it is on a navigation mesh".

Navigation mesh baking can be done either by using a NavigationRegion2D or NavigationRegion3D, or by using the NavigationServer2D and NavigationServer3D API directly.

Baking a navigation mesh with a NavigationRegion

Navigation mesh baking steps

Baking a navigation mesh with agent radius offset from geometry.

The navigation mesh baking is made more accessible with the NavigationRegion node. When baking with a NavigationRegion node, the individual parsing, baking, and region update steps are all combined into one function.

The nodes are available in 2D and 3D as NavigationRegion2D and NavigationRegion3D respectively.

Tip

The navigation mesh source_geometry_mode can be switched to parse specific node group names so nodes that should be baked can be placed anywhere in the scene.

When a NavigationRegion2D node is selected in the Editor, bake options as well as polygon draw tools appear in the top bar of the Editor.

../../_images/nav_region_baking_01.webp

In order for the region to work a NavigationPolygon resource needs to be added.

The properties to parse and bake a navigation mesh are then part of the used resource and can be found in the resource Inspector.

../../_images/nav_region_baking_02.webp

The result of the source geometry parsing can be influenced with the following properties.

  • The parsed_geometry_type that filters if visual objects or physics objects or both should be parsed from the SceneTree. For more details on what objects are parsed and how, see the section about parsing source geometry below.

  • The collision_mask filters which physics collision objects are included when the parsed_geometry_type includes static colliders.

  • The source_geometry_mode that defines on which node(s) to start the parsing, and how to traverse the SceneTree.

  • The source_geometry_group_name is used when only a certain node group should be parsed. Depends on the selected source_geometry_mode.

With the source geometry added, the result of the baking can be controlled with the following properties.

  • The cell_size sets the rasterization grid size and should match the navigation map size.

  • The agent_radius shrinks the baked navigation mesh to have enough margin for the agent (collision) size.

The NavigationRegion2D baking can also be used at runtime with scripts.

var on_thread: bool = true
bake_navigation_polygon(on_thread)

To quickly test the 2D baking with default settings:

  • Add a NavigationRegion2D.

  • Add a NavigationPolygon resource to the NavigationRegion2D.

  • Add a Polygon2D below the NavigationRegion2D.

  • Draw 1 NavigationPolygon outline with the selected NavigationRegion2D draw tool.

  • Draw 1 Polygon2D outline inside the NavigationPolygon outline with the selected Polygon2D draw tool.

  • Hit the Editor bake button and a navigation mesh should appear.

../../_images/nav_region_baking_01.webp ../../_images/nav_mesh_mini_2d.webp

Baking a navigation mesh with the NavigationServer

The NavigationServer2D and NavigationServer3D have API functions to call each step of the navigation mesh baking process individually.

  • parse_source_geometry_data() can be used to parse source geometry to a reusable and serializable resource.

  • bake_from_source_geometry_data() can be used to bake a navigation mesh from already parsed data e.g. to avoid runtime performance issues with (redundant) parsing.

  • bake_from_source_geometry_data_async() is the same but bakes the navigation mesh deferred with threads, not blocking the main thread.

Compared to a NavigationRegion, the NavigationServer offers finer control over the navigation mesh baking process. In turn it is more complex to use but also provides more advanced options.

Some other advantages of the NavigationServer over a NavigationRegion are:

  • The server can parse source geometry without baking, e.g. to cache it for later use.

  • The server allows selecting the root node at which to start the source geometry parsing manually.

  • The server can accept and bake from procedurally generated source geometry data.

  • The server can bake multiple navigation meshes in sequence while (re)using the same source geometry data.

To bake navigation meshes with the NavigationServer, source geometry is required. Source geometry is geometry data that should be considered in a navigation mesh baking process. Both navigation meshes for 2D and 3D are created by baking them from source geometry.

2D and 3D versions of the source geometry resources are available as NavigationMeshSourceGeometryData2D and NavigationMeshSourceGeometryData3D respectively.

Source geometry can be geometry parsed from visual meshes, from physics collision, or procedural created arrays of data, like outlines (2D) and triangle faces (3D). For convenience, source geometry is commonly parsed directly from node setups in the SceneTree. For runtime navigation mesh (re)bakes, be aware that the geometry parsing always happens on the main thread.

Note

The SceneTree is not thread-safe. Parsing source geometry from the SceneTree can only be done on the main thread.

Warning

The data from visual meshes and polygons needs to be received from the GPU, stalling the RenderingServer in the process. For runtime (re)baking prefer using physics shapes as parsed source geometry.

Source geometry is stored inside resources so the created geometry can be reused for multiple bakes. E.g. baking multiple navigation meshes for different agent sizes from the same source geometry. This also allows to save source geometry to disk so it can be loaded later, e.g. to avoid the overhead of parsing it again at runtime.

The geometry data should be in general kept very simple. As many edges as are required but as few as possible. Especially in 2D duplicated and nested geometry should be avoided as it forces polygon hole calculation that can result in flipped polygons. An example for nested geometry would be a smaller StaticBody2D shape placed completely inside the bounds of another StaticBody2D shape.

Baking navigation mesh chunks for large worlds

Building navigation mesh chunks

Building and updating individual navigation mesh chunks at runtime.

See also

You can see the navigation mesh chunk baking in action in the Navigation Mesh Chunks 2D and Navigation Mesh Chunks 3D demo projects.

To avoid misaligned edges between different region chunks the navigation meshes have two important properties for the navigation mesh baking process. The baking bound and the border size. Together they can be used to ensure perfectly aligned edges between region chunks.

Navigation mesh chunk with bake bound and border size

Navigation mesh chunk baked with bake bound or baked with additional border size.

The baking bound, which is an axis-aligned Rect2 for 2D and AABB for 3D, limits the used source geometry by discarding all the geometry that is outside of the bounds.

The NavigationPolygon properties baking_rect and baking_rect_offset can be used to create and place the 2D baking bound.

The NavigationMesh properties filter_baking_aabb and filter_baking_aabb_offset can be used to create and place the 3D baking bound.

With only the baking bound set another problem still exists. The resulting navigation mesh will inevitably be affected by necessary offsets like the agent_radius which makes the edges not align properly.

Navigation mesh chunks with gaps

Navigation mesh chunks with noticeable gaps due to baked agent radius offset.

This is where the border_size property for navigation mesh comes in. The border size is an inward margin from the baking bound. The important characteristic of the border size is that it is unaffected by most offsets and postprocessing like the agent_radius.

Instead of discarding source geometry, the border size discards parts of the final surface of the baked navigation mesh. If the baking bound is large enough the border size can remove the problematic surface parts so that only the intended chunk size is left.

Navigation mesh chunks without gaps

Navigation mesh chunks with aligned edges and without gaps.

Note

The baking bounds need to be large enough to include a reasonable amount of source geometry from all the neighboring chunks.

Warning

In 3D the functionality of the border size is limited to the xz-axis.