游戏 AI - 11

转向行为II

Posted by Kang Cai on September 27, 2020

《转向行为I》一文介绍了 “追逐” 和 “到达” 这两种转向行为,本文将介绍 “对齐” 、 “速度匹配”、“授权行为”。

一、对齐

“对齐” 尝试将角色的方向(orientation)与目标的方向相匹配,它不注意角色或目标的位置或速度。记住,方向(orientation)并不不等同于一般运动学的运动方向(direction)。这种转向行为不会产生任何线性加速度;它只会转动。

“对齐” 的行为与到达的方式类似,它试图到达目标方向并尝试在到达那里时实现零旋转。到达后的大部分代码我们都可以复制,但是朝向会增加我们需要考虑的复杂性。

因为方向角度值每绕 2Pi 的弧度就等效,所以我们不能简单地用目标方向减角色方向,然后从结果中决定我们需要什么旋转。下图显示了两种非常相似的对齐情况,其中角色与目标的角度相同。如果我们简单地减去这两个角,第一个会正确地顺时针旋转一小部分,但是第二个会绕一圈到达相同的位置。

为了找到实际的旋转方向,我们从目标中减去角色的方向,并将结果转换为弧度(-Pi, Pi)。我们通过添加或减去 2Pi 的某个倍数来执行转换,使结果在给定的范围内,我们可以用 mod 函数来计算倍数。大多数游戏引擎或图形库都有一个可用的(在 Unreal Engine 中是 FMath::FindDeltaAngle ,在Unity中是 Mathf.DeltaAngle,但是要知道 Unity 使用度数来表示角度而不是弧度)。

然后我们可以使用转换后的值来控制旋转,算法看起来非常相似。和到达一样,我们使用了两个半径:一个用于减速,另一个作为靠近目标的可接受误差。因为我们处理的是一个标量值,而不是 2D 或 3D 矢量,所以半径是一个区间。

当我们做旋转值的减法时,完全不用考虑角度等效的问题,因为旋转不像方向:一个 Pi 弧度的旋转与 3个 Pi 弧度的旋转不等同。事实上,较大的值表示非常快的旋转,速度非常快的对象(例如赛车中的轮子)可能旋转得非常快,因此我们在这里使用的更新会导致数值不稳定。在 64 位精度的机器上,这不是什么大问题,但在 32 位机器上的早期物理研究经常显示,高速行驶的汽车车轮似乎会抖动。这个问题已经在健壮的物理引擎中解决了,但是值得了解一下,因为我们在这里讨论的代码基本上是实现一个简单的物理更新,这种简单的方法对于中等转速是有效的。

1.1 伪代码

大部分的算法是类似的,只是简单地将位置替换成方向,将向量差替换成角度差。

1.2 性能

时间和空间复杂度仍都是 O(1)。

1.3 反向

要面对一个目标的相反方向,只需在它的方向上增加恒量 Pi,并与那个值保持一致。

二、速度匹配

到目前为止,我们已经看到了试图匹配目标的位置和方向,速度也是一样。

就其本身而言,这种行为很少被使用。它可以用来让角色模仿目标的运动,但这不是很有用。当它与其他行为结合起来时,它就变得至关重要了。例如,它是群集转向行为的组成部分之一

我们已经实现了一个试图匹配速度的算法。到达计算目标速度基于距离目标。然后它试图达到目标速度。我们可以简化到达行为以提供速度匹配实现。

1.1 伪代码

大部分的算法与 “运动学到达” 是类似的,

1.2 性能

时间和空间复杂度仍都是 O(1)。