This document is about: QUANTUM 3
SWITCH TO

Using Navmesh Regions

While respecting performance considerations for deterministic roll-backs in Quantum navmesh Regions are a compromise to Unitys dynamic navmesh carving. They can be used to dynamically toggle pre-defined areas of the navmesh with very little performance overhead.

Because regions are encoded as a mask inside the triangles (unsigned long) the maximum number of different region using the Advanced region import mode ids per map is 64 (Navigation.Constants.MaxRegions). Reusing the same id for different regions is possible in Advanced mode.

The Walkable area always converted to region 0 and called MainArea.

All regions for a map are accessible in this list Map.Regions. A region id is an integer and refers to the index of a region inside that map which can be retrieved using the Map.RegionMap lookup.

Importing Navmesh Regions

Importing Quantum navmesh regions from a Unity navmesh can be done in two different modes.

Region Import Modes

Simple (Quantum SDK 3.0.1)

The Unity navmesh areas are directly mapped as regions and called their respective area names.

This allows only for 30 different regions in total.

Advanced

Additional scripts (QuantumNavMeshRegion) and GameObject with Meshes have to be added to Unity scene. An Unity navmesh area is only used to mark any region, during import it is tried to backtrack from the Unity navmesh triangulation back to the source region script which contains the final region name.

This allows for 64 different regions per map.

Step By Step Tutorial

Step 1) Add areas to Unity navigation areas (Window > AI > Navigation)

Region Areas

Step 2) Select the region import mode and toggle areas that should be converted to regions on the Quantum navmesh import description object MapNavMeshUnity.

Add Region Area

Step 3) [Advanced Mode Only] Setup the Quantum regions caster scripts.

Unity uses a MeshRenderer to project areas onto the navmesh. Create a GameObject with a MeshRenderer and attach the MapNavMeshRegion.

Region Setup

The Id is a unique string that will be accessible from code via the Map.RegionMap from which can later get the region id (int, flag).

CastRegion must be set to CastRegion. The script is re-used for Off Mesh Links for example that do not require to project regions to the navmesh.

NavMeshHelper shows if the GameObject is set up correctly: for example if is it set to static and if the selected overwrite area is a region area.

During the navmesh import the areas that the navmesh triangles are matched back to the original region script using the bounding box of the mesh.

Because triangles are not generated 100% exact MapNavMeshUnity has a setting that adds margin during the fitting (RegionDetectionMargin). The value can be increased if regions are not exported but when it becomes too large there may be problems detecting neighboring regions.

The MeshRenderer and this region script that generate the regions only have to be active during the baking.

Step 4) The map can be baked now using the BakeAll button on the map GameObject (include the Navmesh baking steps).

When selecting the map GameObject the Quantum navmesh gizmos are shown. The colored areas of triangles in the navmesh are the regions. If the gizmos are not shown: Right-click on the Scene tab > Overlays > Quantum Gizmos.

Active Regions

Step 5) Toggle the region globally in the simulation.

C#

public override void OnInit(Frame f) {
    var regionId = f.Map.RegionMap["foo"];
    f.NavMeshRegionMask->ToggleRegion(regionId, false);
}

The NavMeshPathfinder component also has a RegionMask that can be used to toggle off regions for individual agents.

The following screenshot shows a deactivated region with an agent moving around it.

Inactive Regions

Step 6) Region activation is accessible and stored in the frame.

The mask needs to be reset when a new map is loaded. Run FrameBase.ClearAllNavMeshRegions() for example during the ISignalOnMapChanged signal.

C#

public class ResetRegionsSystem : SystemSignalsOnly, ISignalOnMapChanged {
    public void OnMapChanged(Frame f, AssetRefMap previousMap) {
        f.ClearAllNavMeshRegions();
    }
}

The NavMeshRegionMask Class

The NavMeshRegionMask object controls what regions are enabled using an internal bitset.

NavMeshRegionMask.Default - Creates a region mask with all regions enabled.
NavMeshRegionMask.MainArea - Creates a region mask that includes only the MainArea.
NavMeshRegionMask.Empty - Creates a region mask that has no enabled regions.

NavMeshRegionMask.ToggleRegion(int region, bool enabled) - Toggle a region on or off using the region id.
NavMeshRegionMask.IsRegionEnabled(int region) - Test if a region is enabled.
NavMeshRegionMask.Clear() - Reset the mask and sets all regions to enabled.

Back to top