碰撞回避过程

路径跟随时的动态回避是用于计算每帧中的速度以满足以下要求的过程:

动态回避包含以下步骤:

  1. 收集潜在碰撞对象。请参见收集碰撞对象
  2. 针对多种条件生成一组回避速度并对其进行计分。请参见生成回避速度
  3. 选择要应用于给定帧的最合适的速度。请参见用于获取最终得分的实用工具函数

以下部分解释了动态回避过程。

收集碰撞对象

如果基于场景中的整个世界元素计算人物的回避,其成本会非常高。而且,这种方法并不管用,因为回避多为局部回避,并基于附近的实体。

由于时间的连贯性,将在给定帧中回避的实体也可能与后续帧中的大致相同。因此,您可以充分利用 NavMesh 传播结构来构建附近潜在碰撞对象的列表。您只需要以给定的帧速率更新此列表。下图显示了碰撞对象收集范围(显示可回避的实体)。

可以在 ColliderCollectorConfig 中配置此过程。参数如下:

生成回避速度

对于处于任意给定时间的人物,实体可达到较大范围的潜在速度。对于路径跟随以及为回避混乱行为,可以将回避速度集限制在某个固定范围以内。

首先,必须确定全局路径跟随方向。计算此方向以使其与路径跟随过程兼容。

现在,围绕路径跟随方向生成 N 个回避速度的采样。下图显示了生成的速度采样,默认情况下,所有采样得分均为 1.0。

这些速度采样的速度与人物配置中的所需速度一致。可以在 AvoidanceConfig 中配置这些速度采样的数量和角度范围。参数如下:

现在可以执行计分过程以选择最佳速度。

碰撞时间

回避在空间和时间方面都是局部的。可以指定用作范围的时间限制,并使用针对每个采样收集的碰撞对象计算碰撞时间。下图显示了为给定帧计算的碰撞时间。

如果没有碰撞,或碰撞超出了配置的时间限制,可以将采样成本设置为时间限制。

NavMesh/通道边界

可以基于采样与 NavMesh/通道边界之间的距离来对采样计分。下图显示了 NavMesh 外的采样获得了较差的分数。

碰撞时间比例

可以将具有范围的碰撞时间进行拆分以计算 0.0 和 1.0f 之间的比例,其中 1.0f 是最安全的速度。下图将碰撞时间显示为比例。

可以在 AvoidanceConfig 中指定时间范围。参数如下:

  • m_minimalTimeToCollision – 如果障碍物在 N 秒内与其他障碍物碰撞,在回避时应考虑此参数。
  • m_safetyDistance – 围绕碰撞对象的安全距离,以避免移动得太近。可以按安全距离稍微展开碰撞对象的大小,以拾取与碰撞对象保持较远距离的速度。

平滑

采样可能不准确,因为有效采样与无效采样之间可能仅有几度之差。若要避免拾取不安全的采样,可以为每个速度采样及其相邻的采样计算平均碰撞时间比例。下图显示了平滑碰撞时间。

现在可以选择没有碰撞的安全速度。但是,有几种可能性,因此可以考虑其他两个条件来作出决定。

所需速度

路径跟随已产生所需速度。可以利用此速度来基于采样相对此速度的距离为采样计分。下图显示了如何将所需速度(绿色)用于基于采样相对此速度的距离为采样计分。

上一个速度

若要更进一步稳定,可以执行相对于先前已计算速度的类似计算。下图显示了如何基于上一个速度(红色)进行计分。

用于获取最终得分的实用工具函数

可以对每个采样使用以下实用工具函数并计算最终得分。

Final Score = (A * CollisionTimeRatio) + (B * DesiredVelocityDistance) + (C *  PreviousVelocityDistance)
其中,A、B 和 C 是可以配置的常量(如果 A +B + C = 1.0 的话最容易理解)。在获得最终得分之后,只需返回其采样具有最高得分的速度。下图显示了针对回避输出的所选最终得分和最终速度。

可以在 AvoidanceConfig 中配置 A、B 和 C。参数如下:

停止

当没有好的回避解决方案时,如果下一个碰撞时间低于给定阈值,可以返回实体的零速度以停止。参数如下:

在某些情况下,您可能希望首先降低速度,甚至禁用实体停止功能。参数如下:

如果受阻太久,您可能仍然想强制通行。参数如下: