Sometimes you want to tweak the navmesh on a per-object basis. For example you might want to make some objects completely unwalkable, or you might want to special case some objects to remove them from the navmesh altogether.
You can do this using the RecastMeshObj component. Attach it to any object you want to modify and configure the settings as you wish.
Make the surfaces of an object walkable (this is just the default behavior).
Create seams in the navmesh between adjacent objects.
Mark the surfaces of an object with a specific tag (see Working with tags).
Adding this component to an object will make sure it is included in any recast graphs. It will be included even if the Rasterize Meshes toggle is set to false.
Using RecastMeshObjs instead of relying on the Rasterize Meshes option is good for several reasons.
Rasterize Meshes is slow. If you are using a tiled graph and you are updating it, every time something is recalculated the graph will have to search all meshes in your scene for ones to rasterize, in contrast, RecastMeshObjs are stored in a tree for extremely fast lookup (O(log n + k) compared to O(n) where n is the number of meshes in your scene and k is the number of meshes which should be rasterized, if you know Big-O notation).
The RecastMeshObj exposes some options which can not be accessed using the Rasterize Meshes toggle. See member documentation for more info. This can for example be used to include meshes in the recast graph rasterization, but make sure that the character cannot walk on them.
Since the objects are stored in a tree, and trees are slow to update, there is an enforcement that objects are not allowed to move unless the dynamic option is enabled. When the dynamic option is enabled, the object will be stored in an array instead of in the tree. This will reduce the performance improvement over 'Rasterize Meshes' but is still faster.
If a mesh filter and a mesh renderer is attached to this GameObject, those will be used in the rasterization otherwise if a collider is attached, that will be used.
Public Methods
GetBounds
()
Bounds completely enclosing the mesh for this object.
Recalculation of bounding box trees is expensive so if this is true, the object will simply be stored in an array. Easier to move, but slower lookup, so use wisely. If you for some reason want to move it, but don't want it dynamic (maybe you will only move it veery seldom and have lots of similar objects so they would add overhead by being dynamic). You can enable and disable the component every time you move it. Disabling it will remove it from the bounding box tree and enabling it will add it to the bounding box tree again.
The object should never move unless being dynamic or disabling/enabling it as described above.
If true then the mesh will be treated as solid and its interior will be unwalkable.
Public
bool
solid = false
If true then the mesh will be treated as solid and its interior will be unwalkable.
The unwalkable region will be the minimum to maximum y coordinate in each cell.
If you enable this on a mesh that is actually hollow then the hollow region will also be treated as unwalkable.
surfaceID
Voxel area for mesh.
Public
int
surfaceID = 1
Voxel area for mesh.
This area (not to be confused with pathfinding areas, this is only used when rasterizing meshes for the recast graph) field can be used to explicitly insert edges in the navmesh geometry or to make some parts of the mesh unwalkable.
When rasterizing the world and two objects with different surface id values are adjacent to each other, a split in the navmesh geometry will be added between them, characters will still be able to walk between them, but this can be useful when working with navmesh updates.
Navmesh updates which recalculate a whole tile (updatePhysics=True) are very slow So if there are special places which you know are going to be updated quite often, for example at a door opening (opened/closed door) you can use surface IDs to create splits on the navmesh for easier updating using normal graph updates (updatePhysics=False). See the below video for more information.
When mode is set to Mode.WalkableSurfaceWithTag then this value will be interpreted as a pathfinding tag. See Working with tags.
Note
This only has an effect if mode is set to Mode.WalkableSurfaceWithSeam or Mode.WalkableSurfaceWithTag.
Only non-negative values are valid.
Public Enums
Mode
Public
Mode
ExcludeFromGraph
This object will be completely ignored by the graph.
UnwalkableSurface
All surfaces on this mesh will be made unwalkable.
WalkableSurface
All surfaces on this mesh will be walkable.
WalkableSurfaceWithSeam
All surfaces on this mesh will be walkable and a seam will be created between the surfaces on this mesh and the surfaces on other meshes (with a different surface id)
WalkableSurfaceWithTag
All surfaces on this mesh will be walkable and the nodes will be given the specified tag.
A seam will be created between the surfaces on this mesh and the surfaces on other meshes (with a different tag or surface id)
Private/Protected Members
Awake
()
Protected
void
Awake ()
OnDisable
()
Private
void
OnDisable ()
OnEnable
()
Private
void
OnEnable ()
OnUpgradeSerializedData
(version, unityThread)
Handle serialization backwards compatibility.
Protected
int
OnUpgradeSerializedData (
int
version
bool
unityThread
)
Handle serialization backwards compatibility.
RecalculateBounds
()
Recalculates the internally stored bounds of the object.
Private
void
RecalculateBounds ()
Recalculates the internally stored bounds of the object.
Register
()
Private
void
Register ()
Reset
()
Handle serialization backwards compatibility.
Protected
void
Reset ()
Handle serialization backwards compatibility.
_dynamic
Private
bool
_dynamic
dynamicMeshObjs
Dynamic objects are stored in a list since it is costly to update the tree every time they move.
Static objects are stored in a tree for fast bounds lookups.
Deprecated Members
area
Voxel area for mesh.
Public
int
area
Voxel area for mesh.
This area (not to be confused with pathfinding areas, this is only used when rasterizing meshes for the recast graph) field can be used to explicitly insert edges in the navmesh geometry or to make some parts of the mesh unwalkable.
When rasterizing the world and two objects with different surface id values are adjacent to each other, a split in the navmesh geometry will be added between them, characters will still be able to walk between them, but this can be useful when working with navmesh updates.
Navmesh updates which recalculate a whole tile (updatePhysics=True) are very slow So if there are special places which you know are going to be updated quite often, for example at a door opening (opened/closed door) you can use surface IDs to create splits on the navmesh for easier updating using normal graph updates (updatePhysics=False). See the below video for more information.