A* Pathfinding Project  4.1.19
The A* Pathfinding Project for Unity 3D
NavmeshCut Class Reference

Navmesh cutting is used for fast recast/navmesh graph updates. More...

Detailed Description

Navmesh cutting is used for fast recast/navmesh graph updates.

Navmesh cutting is used to cut holes into an existing navmesh generated by a recast or navmesh graph. Recast/navmesh graphs usually only allow either just changing parameters on existing nodes (e.g make a whole triangle unwalkable) which is not very flexible or recalculate a whole tile which is pretty slow. With navmesh cutting you can remove (cut) parts of the navmesh that is blocked by obstacles such as a new building in an RTS game however you cannot add anything new to the navmesh or change the positions of the nodes. This is significantly faster than recalculating whole tiles from scratch in a recast graph.

The NavmeshCut component uses a 2D shape to cut the navmesh with. A rectangle and a circle shape is built in, but you can also specify a custom mesh to use.

Note that the shape is not 3D so if you rotate the cut you will see that the 2D shape will be rotated and then just projected down on the XZ plane.

In the scene view the NavmeshCut looks like an extruded 2D shape because a navmesh cut also has a height. It will only cut the part of the navmesh which it touches. For performance reasons it only checks the bounding boxes of the triangles in the navmesh, so it may cut triangles whoose bounding boxes it intersects even if the triangle does not intersect the extruded shape. However in most cases this does not make a large difference.

It is also possible to set the navmesh cut to dual mode by setting the isDual field to true. This will prevent it from cutting a hole in the navmesh and it will instead just split the navmesh along the border but keep both the interior and the exterior. This can be useful if you for example want to change the penalty of some region which does not neatly line up with the navmesh triangles. It is often combined with the GraphUpdateScene component (however note that the GraphUpdateScene component will not automatically reapply the penalty if the graph is updated again).

By default the navmesh cut does not take rotation or scaling into account. If you want to do that, you can set the useRotationAndScale field to true. This is a bit slower, but it is not a very large difference.

Version
In 3.x navmesh cutting could only be used with recast graphs, but in 4.x they can be used with both recast and navmesh graphs.

Custom meshes
For most purposes you can use the built-in shapes, however in some cases a custom cutting mesh may be useful. The custom mesh should be a flat 2D shape like in the image below. The script will then find the contour of that mesh and use that shape as the cut. Make sure that all normals are smooth and that the mesh contains no UV information. Otherwise Unity might split a vertex and then the script will not find the correct contour. You should not use a very high polygon mesh since that will create a lot of nodes in the navmesh graph and slow down pathfinding because of that. For very high polygon meshes it might even cause more suboptimal paths to be generated if it causes many thin triangles to be added to the navmesh.

Control updates through code
Navmesh cuts are applied periodically, but sometimes you may want to ensure the graph is up to date right now. Then you can use the following code.

// Schedule pending updates to be done as soon as the pathfinding threads
// are done with what they are currently doing.
// Block until the updates have finished

You can also control how often the scripts check for if any navmesh cut has changed. If you have a very large number of cuts it may be good for performance to not check it as often.

// Check every frame (the default)
AstarPath.active.navmeshUpdates.updateInterval = 0;
// Check every 0.1 seconds
AstarPath.active.navmeshUpdates.updateInterval = 0.1f;
// Never check for changes
AstarPath.active.navmeshUpdates.updateInterval = -1;
// You will have to schedule updates manually using

You can also find this setting in the AstarPath inspector under Settings.

Navmesh cutting and tags/penalties
Because navmesh cutting can modify the triangles in the navmesh pretty much abitrarily it is not possible to keep tags and penalties when updating the graph. The tags and penalties will be preserved for nodes which stay exactly the same when an update is applied though.

If you need to use tags, the only stable way to keep them is to apply all the graph updates that set them every time a navmesh cut update has been done. This is of course relatively slow, but it will at least work.

A* Pro Feature:
This is an A* Pathfinding Project Pro feature only. This function/class/variable might not exist in the Free version of the A* Pathfinding Project or the functionality might be limited
The Pro version can be bought here

See also
http://www.arongranberg.com/2013/08/navmesh-cutting/

Public Types

enum  MeshType { Rectangle, Circle, CustomMesh }
 

Public Member Functions

override void ForceUpdate ()
 Forces this navmesh cut to update the navmesh. More...
 
void GetContour (List< List< Vector3 > > buffer)
 World space contour of the navmesh cut. More...
 
void OnDrawGizmos ()
 
void OnDrawGizmosSelected ()
 
override bool RequiresUpdate ()
 Returns true if this object has moved so much that it requires an update. More...
 
virtual void UsedForCut ()
 Called whenever this navmesh cut is used to update the navmesh. More...
 

Public Attributes

Vector3 center
 
float circleRadius = 1
 Radius of the circle. More...
 
int circleResolution = 6
 Number of vertices on the circle. More...
 
bool cutsAddedGeom = true
 Cuts geometry added by a NavmeshAdd component. More...
 
float height = 1
 The cut will be extruded to this height. More...
 
bool isDual
 Only makes a split in the navmesh, but does not remove the geometry to make a hole. More...
 
Mesh mesh
 Custom mesh to use. More...
 
float meshScale = 1
 Scale of the custom mesh, if used. More...
 
Vector2 rectangleSize = new Vector2(1, 1)
 Size of the rectangle. More...
 
MeshType type
 Shape of the cut. More...
 
float updateDistance = 0.4f
 Distance between positions to require an update of the navmesh. More...
 
float updateRotationDistance = 10
 How many degrees rotation that is required for an update to the navmesh. More...
 
bool useRotationAndScale
 Includes rotation and scale in calculations. More...
 

Static Public Attributes

static readonly Color GizmoColor = new Color(37.0f/255, 184.0f/255, 239.0f/255)
 

Protected Member Functions

override void Awake ()
 
override void OnEnable ()
 
- Protected Member Functions inherited from NavmeshClipper
virtual void OnDisable ()
 
- Protected Member Functions inherited from VersionedMonoBehaviour
virtual int OnUpgradeSerializedData (int version, bool unityThread)
 Handle serialization backwards compatibility. More...
 

Protected Attributes

Transform tr
 cached transform component More...
 

Package Functions

override Rect GetBounds (Pathfinding.Util.GraphTransform inverseTranform)
 Bounds in XZ space after transforming using the *inverse* transform of the inverseTranform parameter. More...
 
float GetY (Pathfinding.Util.GraphTransform transform)
 Y coordinate of the center of the bounding box in graph space. More...
 
override void NotifyUpdated ()
 Internal method to notify the NavmeshCut that it has just been used to update the navmesh. More...
 

Private Member Functions

void CalculateMeshContour ()
 
void TransformBuffer (List< Vector3 > buffer, bool reverse)
 

Private Attributes

Vector3 [][] contours
 
Mesh lastMesh
 
Vector3 lastPosition
 
Quaternion lastRotation
 

Static Private Attributes

static readonly Dictionary< Int2, int > edges = new Dictionary<Int2, int>()
 Cached variable, to avoid allocations. More...
 
static readonly Dictionary< int, int > pointers = new Dictionary<int, int>()
 Cached variable, to avoid allocations. More...
 

Additional Inherited Members

- Static Public Member Functions inherited from NavmeshClipper
static void AddEnableCallback (System.Action< NavmeshClipper > onEnable, System.Action< NavmeshClipper > onDisable)
 
static void RemoveEnableCallback (System.Action< NavmeshClipper > onEnable, System.Action< NavmeshClipper > onDisable)
 
- Properties inherited from NavmeshClipper
static List< NavmeshClipperallEnabled [get]
 All navmesh clipper components in the scene. More...
 

Member Enumeration Documentation

◆ MeshType

enum MeshType
strong
Enumerator
Rectangle 
Circle 
CustomMesh 

Member Function Documentation

◆ Awake()

override void Awake ( )
protectedvirtual

Reimplemented from VersionedMonoBehaviour.

◆ CalculateMeshContour()

void CalculateMeshContour ( )
private

◆ ForceUpdate()

override void ForceUpdate ( )
virtual

Forces this navmesh cut to update the navmesh.

Note
Dynamic updating requires a Tile Handler Helper somewhere in the scene. This update is not instant, it is done the next time the TileHandlerHelper checks this instance for if it needs updating.
See also
TileHandlerHelper.ForceUpdate()

Implements NavmeshClipper.

◆ GetBounds()

override Rect GetBounds ( Pathfinding.Util.GraphTransform  inverseTranform)
packagevirtual

Bounds in XZ space after transforming using the *inverse* transform of the inverseTranform parameter.

The transformation will typically transform the vertices to graph space and this is used to figure out which tiles the cut intersects.

Implements NavmeshClipper.

◆ GetContour()

void GetContour ( List< List< Vector3 > >  buffer)

World space contour of the navmesh cut.

Fills the specified buffer with all contours. The cut may contain several contours which is why the buffer is a list of lists.

◆ GetY()

float GetY ( Pathfinding.Util.GraphTransform  transform)
package

Y coordinate of the center of the bounding box in graph space.

◆ NotifyUpdated()

override void NotifyUpdated ( )
packagevirtual

Internal method to notify the NavmeshCut that it has just been used to update the navmesh.

Implements NavmeshClipper.

◆ OnDrawGizmos()

void OnDrawGizmos ( )

◆ OnDrawGizmosSelected()

void OnDrawGizmosSelected ( )

◆ OnEnable()

override void OnEnable ( )
protectedvirtual

Reimplemented from NavmeshClipper.

◆ RequiresUpdate()

override bool RequiresUpdate ( )
virtual

Returns true if this object has moved so much that it requires an update.

When an update to the navmesh has been done, call NotifyUpdated to be able to get relavant output from this method again.

Implements NavmeshClipper.

◆ TransformBuffer()

void TransformBuffer ( List< Vector3 >  buffer,
bool  reverse 
)
private

◆ UsedForCut()

virtual void UsedForCut ( )
virtual

Called whenever this navmesh cut is used to update the navmesh.

Called once for each tile the navmesh cut is in. You can override this method to execute custom actions whenever this happens.

Member Data Documentation

◆ center

Vector3 center

◆ circleRadius

float circleRadius = 1

Radius of the circle.

◆ circleResolution

int circleResolution = 6

Number of vertices on the circle.

◆ contours

Vector3 [][] contours
private

◆ cutsAddedGeom

bool cutsAddedGeom = true

Cuts geometry added by a NavmeshAdd component.

You rarely need to change this

◆ edges

readonly Dictionary<Int2, int> edges = new Dictionary<Int2, int>()
staticprivate

Cached variable, to avoid allocations.

◆ GizmoColor

readonly Color GizmoColor = new Color(37.0f/255, 184.0f/255, 239.0f/255)
static

◆ height

float height = 1

The cut will be extruded to this height.

◆ isDual

bool isDual

Only makes a split in the navmesh, but does not remove the geometry to make a hole.

This is slower than a normal cut

◆ lastMesh

Mesh lastMesh
private

◆ lastPosition

Vector3 lastPosition
private

◆ lastRotation

Quaternion lastRotation
private

◆ mesh

Mesh mesh

Custom mesh to use.

The contour(s) of the mesh will be extracted. If you get the "max perturbations" error when cutting with this, check the normals on the mesh. They should all point in the same direction. Try flipping them if that does not help.

This mesh should only be a 2D surface, not a volume.

◆ meshScale

float meshScale = 1

Scale of the custom mesh, if used.

◆ pointers

readonly Dictionary<int, int> pointers = new Dictionary<int, int>()
staticprivate

Cached variable, to avoid allocations.

◆ rectangleSize

Vector2 rectangleSize = new Vector2(1, 1)

Size of the rectangle.

◆ tr

Transform tr
protected

cached transform component

◆ type

MeshType type

Shape of the cut.

◆ updateDistance

float updateDistance = 0.4f

Distance between positions to require an update of the navmesh.

A smaller distance gives better accuracy, but requires more updates when moving the object over time, so it is often slower.

Note
Dynamic updating requires a TileHandlerHelper somewhere in the scene.

◆ updateRotationDistance

float updateRotationDistance = 10

How many degrees rotation that is required for an update to the navmesh.

Should be between 0 and 180.

Note
Dynamic updating requires a Tile Handler Helper somewhere in the scene.

◆ useRotationAndScale

bool useRotationAndScale

Includes rotation and scale in calculations.

This is slower since a lot more matrix multiplications are needed but gives more flexibility.


The documentation for this class was generated from the following file: