API

Adding and removing obstacles

Prerequisites

Internally, a navigation mesh with support for obstacles differs from the 'standard' use case of a single static navigation mesh. Obstacles mark tiles as dirty. Those tiles need to be reprocessed to compute a portion of the navigation mesh. To do so, Recast introduces the concept of tiles. Each tile is a square portion of the nav mesh. Tiles are processed each frame. This makes large changes process over a couple of frames.

In order to build a Tiled nav mesh instead of a single mesh, add the following lines to the nav mesh creation parameters:

const navmeshParameters = {
cs: 0.2,
ch: 0.2,
walkableSlopeAngle: 0,
walkableHeight: 0.0,
walkableClimb: 0,
walkableRadius: 1,
maxEdgeLen: 12,
maxSimplificationError: 1.3,
minRegionArea: 8,
mergeRegionArea: 20,
maxVertsPerPoly: 6,
detailSampleDist: 6,
detailSampleMaxError: 15,
borderSize: 1,
tileSize: 20,
};

Note the addition of tileSize. It is the world-unit size of each tile. If it is not present or has a value of zero, it falls back to the standard use case and obstacles will not work. Also, depending on your use case, this value must be chosen carefully to balance too many tiles against overly CPU-intensive updates.

Note : The ComputePath method will handle obstacles only when a crowd has been instantiated. Otherwise, the path will adhere to the navmesh without considering obstacles. If your use case involves computing a path with obstacles, agents are optional, but a crowd is mandatory.

Obstacles API

Once the navigation mesh is updated to take tiles into account, obstacles are accessible through 3 simple functions:

addCylinderObstacle(position: Vector3, radius: number, height: number): IObstacle;
addBoxObstacle(position: Vector3, extent: Vector3, angle: number): IObstacle;
removeObstacle(obstacle: IObstacle): void;

Keep a list of added obstacles in order to remove them later. An obstacle that is not colliding with the navigation mesh will have no influence.

Adding a door to a navigation mesh