Collision Avoidance Process

Dynamic avoidance while path following is a process that computes a velocity in each frame to meet these requirements:

Dynamic avoidance consists of these steps:

  1. Collect the potential colliders. See Collecting the Colliders below.
  2. Generate and score a set of avoidance velocities on various criteria. See Generating the Avoidance Velocity below.
  3. Choose the most suitable velocity to apply in the given frame. See Utility Function for Final Score below.

The following sections explain the dynamic avoidance process.

Collecting the Colliders

It is costly to compute the avoidance for a bot based on the entire world elements in a scene. Moreover, it does not serve the purpose because avoidance is mostly local and based on nearby entities.

It is also likely that the entities to avoid in a given frame are roughly the same in the subsequent frames because of time coherence. Therefore, you can leverage the NavMesh propagation structure to build a list of nearby potential colliders. You only need to update this list at a given frame rate. The following figure shows the collider collection extent displaying the entities that you can avoid.

You can configure this process in ColliderCollectorConfig. Following are the parameters:

Generating the Avoidance Velocity

For a bot at any given time, the entity can reach a wide range of potential velocities. For path following and to avoid chaotic behaviors, you can limit the set of avoidance velocities to a fixed range.

First, a global path following direction must be determined. This direction is computed to be compatible with the path following process.

Now, generate samples of N avoidance velocities around the path following direction. The following figure shows the generated velocity samples, all scored to 1.0 by default.

The speed of these velocities matches the desired speed in the bot config. You can configure the number and angle span for these velocity samples in AvoidanceConfig. Following are the parameters:

You can now perform a scoring process to choose which velocity is the best.

Collision Time

The avoidance is both local in space and in time. You can specify a time limit that serves as a horizon, and compute a collision time with the collected colliders for each sample. The following figure shows the collision time computed for a given frame.

If there are no collisions, or if the collision is beyond the configured time limit, you can set the sample cost as the time limit.

You can score the samples based on their distance from the NavMesh/channel boundaries. The following figure shows that samples leading outside the NavMesh get a bad score.

Time to Collision Ratio

You can divide the collision time with the horizon to compute a ratio between 0.0 and 1.0f, where 1.0f is the safest velocity. The following figure shows the collision time as a ratio.

You can specify the time horizon in AvoidanceConfig. Following are the parameters:

Smoothing

Sampling might be inaccurate because only a few degrees separate a valid sample from an invalid one. To avoid picking samples that are not safe, you can compute the average collision time ratio for each velocity sample with its neighbors. The following figure shows the smooth collision time.

You can now choose safe collision free velocities. However, there are several possibilities, so you can consider two other criteria to decide.

Desired Velocity

The path following already produced a desired velocity. You can leverage this velocity to score the samples based on how far they are relative to this velocity. The following figure shows how the desired velocity (in green) is used to score the samples based on how far they are from it.

Previous Velocity

To stabilize even further, you can perform a similar computation relative to the previously computed velocity. The following figure shows how scoring is based on the previous velocity (in red).

Utility Function for Final Score

You can use the following utility function for each sample and compute the final score.

Final Score = (A * CollisionTimeRatio) + (B * DesiredVelocityDistance) + (C *  PreviousVelocityDistance)

Where, A, B, and C are constants that you can configure (best understood if A +B + C = 1.0). After you get the final score, simply return the velocity whose sample has the highest score. The following figure shows the chosen final score and final velocity to output for avoidance.

You can configure A, B, and C in AvoidanceConfig. Following are the parameters:

Stopping

When there are no good avoidance solutions, you can return a zero velocity for the entity to stop if the next collision time is below a given threshold. Following are the parameters:

In some cases, you might prefer slowing down first, or even disabling the ability of the entity to stop. Following are the parameters:

You might still want to force the passage if you are blocked for too long. Following are the parameters: