Skip to content

Dynamic Obstacles

An additional GridBuilder class is included for use with dynamic obstacles. This let's you build a large grid once with static, non-moving obstacles (usually the map), then regularly update non-fixed / dynamic obstacles (usually pathfinding agents) without needing to rebuild the entire grid.

This prevents re-allocation, garbage collection, and collision detection each frame you need the grid.

  1. Register your dynamic obstacles
  2. Move obstacles between path requests any amount
  3. Call BuildDynamic()

PathfindingDynamicGridBuilder

This grid builder includes all the base functionality from Grid Builders, but handles dynamic obstacles internally.

Register Obstacles

Registered obstacles will be queried for their blocking tiles on BuildDynamic()

public void RegisterDynamicObstacle(IDynamicObstacle obstacle)
public void UnregisterDynamicObstacle(IDynamicObstacle obstacle)

Collision

Collision is determined by the same collision settings that were used to build the static grid.

Layers

Collision is check on a per-tile basis using ray-casts by default. Ensure that the dynamic obstacles are on a different Layer than your static grid.

At runtime, check the current state of the dynamic matrix (not including static obstacles) with:

public bool IsDynamicBlocked(Vector3 worldPosition)

Obstacles

Obstacles can be anything they just need to inherit from IDynamicObstacle and provide their world position. If you need more complicated collision, IIrregularDynamicObstacle checks the Bounds using the specified collision settings.

public interface IDynamicObstacle
{
    /// <summary> The blocking position of the tile (grid tile center) </summary>
    Vector3 WorldPosition { get; }

    public bool TryGetGameObject(out GameObject obj);
}
public interface IIrregularDynamicObstacle : IDynamicObstacle
{
    /// <summary> World-space bounds of this obstacle. </summary>
    Bounds WorldBounds { get; }

    /// <summary> Layer mask for detecting this obstacle's blocking tiles within the bounds. </summary>
    LayerMask LayerMask { get; }
}

Advanced Usage

invalidatePathsOnDynamicRebuild is false by default, override in a child class or change the source if you DO want to invalidate paths when calling BuildDynamic(). The callback is still executed but the result is PathResult.EPathJobStatus.Cancelled_Rebuild. In this case the resulting path is null.