2017年9月22日

《The Occupation》中实现 AI 运动的分层方法

作者 James Burton


大家好,我是 White Paper Games 的技术技术美术师 James Burton。本博客的目的是为了展示我们在即将推出的游戏《The Occupation》中创造 AI 角色运动系统的流程。我跟我们的 AI 设计师 Jonny Pickton、动画师 Robert Beard 和程序员 Martin Cosens 共同研发出这个系统。首先我要说的是,在创建这个系统之前,我们团队从来没有过任何角色动画经验(或者相关的任何角色经验)。我们并不是想要宣称自己是首创这一系统,只是找到了一种适合我们项目的解决方案,我们认为应该与大家分享。希望听到大家的反馈或评论,帮助我们改进设置!本文末尾提供了我们的联系方式。

通过这个运动系统,我们需要实现的关键功能包括:

  • 模块化,非破坏性元素(添加或删除层不会导致角色停止工作或影响其他层)。
  • 编码需求低,因为我们只有一个程序员。
  • 色调适宜,因为我们的游戏没有战斗,AI 是可被观察的、平静的存在。扫射动画并不适用。
  • 系统尽量使用 UE4 默认值。
  • 系统尽量保持匀速和恒定的转身速率。

在此之前,我们试过了一些其他方法:

完全根节点运动设置:看起来不错,但实际上不满足 AI 完成其他任务的精度要求。

根节点运动/关节囊驱动混合:转身使用根节点运动,其他动作使用关节囊驱动运动。在当时混合使用根节点运动速度和关节囊存在问题 - 因此决定放弃。

最后,我们采用了完全由关节囊驱动的系统,加入了一些技巧,让我们能够将关节囊的速度与动画播放匹配起来 - 但后来的需求越来越多。

以下是任一情况下未经编辑的 UE4 默认设置的效果。大家可以看到,角色走了一圈,在场景里四处走动,但看起来不是很自然:

所以我们尝试修复这个问题。

第 1 层 - 原地转身

首先我们集中处理基本层设置。这样,设计师们可以处理角色,而我们也有基本保真度水平。对我们来说,这意味着让角色原地转身,面朝导航路线中的下一个目标点:

  • 动画是以恒定转速编写的。
  • 我们根据角色所需的转身角度调整了动画的播放速度。为此,我们按照角色的转速划分了所需的转身角度。这让我们实现了所需的转身的旋转时间。然后用原始动画长度(以秒为单位)除以所需的旋转时间,就得出了转身动画的播放速度。
  • 这是非常基本的设置,甚至可以直接交付给某些游戏。

Unreal+Engine%2FblogAssets%2F2017%2FSEPTEMBER+2017%2FThe+Occupation+Animation+Tech+Blog%2FIMG1_PlayRateFormula-770x132-40cf6c29f58fbaa0033e828f464617ccc7d473e3
Unreal+Engine%2FblogAssets%2F2017%2FSEPTEMBER+2017%2FThe+Occupation+Animation+Tech+Blog%2FIMG2_ScalePlayrateforSpotTurns-770x175-98be8e33b4c57bc70b85d6a9b95c2c021713904a

以下是效果视频,以及为这一层编写的一些 GIF 动画:

Unreal+Engine%2FblogAssets%2F2017%2FSEPTEMBER+2017%2FThe+Occupation+Animation+Tech+Blog%2FGIF1_-TurnonSpot45-6b7174660396fbf8fd3f40b479cd6b6ec61d4752

Unreal+Engine%2FblogAssets%2F2017%2FSEPTEMBER+2017%2FThe+Occupation+Animation+Tech+Blog%2FGIF2_TurnonSpot90-073c83b7a4226c2fc49d361f7e961acb6f1e0a51Unreal+Engine%2FblogAssets%2F2017%2FSEPTEMBER+2017%2FThe+Occupation+Animation+Tech+Blog%2FGIF3_TurnonSpot180-e4e18cc4f6b2d412ec8dfa69909f45e3b26d9a21 







  [原地转身 45]             [换地转身 90]         [原地转身 180]

第 2 层 - 开始行走

下一层是开始行走 - 这样角色可以加速到基本行走速度,而不是突然跳入行走姿势。由于我们在这里要处理加速,并且希望所有动作都是关节囊驱动的,所以写了一个小工具。这是一个非常简单的工具,因为我的编码经验非常非常有限,这个工具是使用 MEL 做的。这个工具编写了一个曲线,用于描述这个角色在每一帧的速度,从而映射加速。那么具体是怎样的过程呢?我们让动画师做了一个动画,利用简单数学计算做了个样本:

Unreal+Engine%2FblogAssets%2F2017%2FSEPTEMBER+2017%2FThe+Occupation+Animation+Tech+Blog%2FIMG3_Speed-Formula-770x132-88308d0bf30bd9c23e0257059d7cb20906cad618

请注意 TranslateX.F2 – TranslateX.F1 只是表示动画的当前帧减去上一帧,计算出这两帧之间的运动量。然后用这个差值除以按所需 FPS(有些动画师使用 24fps,还有些使用 30… 等等)走过一帧所用的时间。

幸运的是,我们可以将这个数据与骨架根骨骼上的属性关联起来,然后导入到 UE4 时,确保打开“导入自定义属性”。这样会确保它作为一个曲线加到动画资产中。我应该提到过,这是虚幻引擎中的一个超酷功能,让我们有机会进行许多其他很棒的设置!

Unreal+Engine%2FblogAssets%2F2017%2FSEPTEMBER+2017%2FThe+Occupation+Animation+Tech+Blog%2FIMG4_CustomSpeedAttribute-770x136-807d4ff0104f8ea1c74066bf17f4dbdc1777ca83

然后我们用这个曲线设置了角色的最大速度,一切就准备就绪了!

以下是这个设置的效果以及所编动画的一些 GIF:

Unreal+Engine%2FblogAssets%2F2017%2FSEPTEMBER+2017%2FThe+Occupation+Animation+Tech+Blog%2FGIF4_StartWalkFWD-825c8ec73e8e1cb5fa734fb78a7286463a763b0aUnreal+Engine%2FblogAssets%2F2017%2FSEPTEMBER+2017%2FThe+Occupation+Animation+Tech+Blog%2FGIF5_StartWalk90-a82bd63e1a2266b368bc4147c1e2fad50705c5a4 Unreal+Engine%2FblogAssets%2F2017%2FSEPTEMBER+2017%2FThe+Occupation+Animation+Tech+Blog%2FGIF6_StartWalk-90-aa415b13dc1ba39be1fcdcf4a87b6aef44304537             







 [开始行走 FWD]              [开始行走 90]                  [开始行走 -90]

第 3 层 - 停止行走

这个就非常简单了,因为它的设置跟“开始行走”完全一样,但是为了让角色知道何时开始播放“停止动画”,我们需要程序员在 UE4 中写点代码来让它发挥作用。

这段代码会查找路线中的最后一个点,然后触发一个事件,在距离终点的所需长度位置(这个是动画师在制作动画时指定的,但距离最好尽量短!)“播放停止动画”。

终点的接受半径导致会出现一点脚步滑动 - 在以下示例中较为明显,但稍作调整就可以更正此问题。对我们来说,角色完美地到达最终位置是十分重要的,因为其他动画是从这里开始播放的,所以让这些动画与这一点咬合,这样如果出现了一些错误,也能确保其余部分正常工作。

以下是具体效果视频以及所编动画的一些 GIF:

Unreal+Engine%2FblogAssets%2F2017%2FSEPTEMBER+2017%2FThe+Occupation+Animation+Tech+Blog%2FGIF7_WalkStopFWD-2362243ea8baeb8abf63c7e2146448b9f023f6ea

[向前行走停止]

第 4 层 - 伪造弯曲路线

这是最难解决的问题,需要进行一些编码,但也正是因为有了这一层,才让整体运动系统看起来与众不同。

在这里,基本上是让角色离开导航路线,让她沿着向前矢量驱动自己的动作,然后转弯,面向下一个点。用图片说明更为清晰,请参见下图:

Unreal+Engine%2FblogAssets%2F2017%2FSEPTEMBER+2017%2FThe+Occupation+Animation+Tech+Blog%2FIMG5_TurnExplanationImage-770x770-e93ebd25ac4ef7413b9c28c7a9e8f2015a8e60bd

重要的是要利用角色关节囊的恒定旋转和速度 - 这样数学计算就比较简单。

以下是具体效果视频:

幸运的是,我们不必为此编写任何动画,因为没有动画看起来已经很不错了!

第 5 层 - 转身预期(噢!一块糖!)

这是一个很好的附加组件,可以让角色感觉像是期待转身。对我们来说,这包括在实际开始转身之前,让她朝着转身的方向稍微地转头,扭转身体。

这需要一点技巧,因为不能简单地使用下一个点,然后通过线性插值计算旋转。

最后做了一个系统,使用“引诱”来计算角色前面的导航点之间的线性插值,利用“目标偏移”让角色身体和头部始终朝向转身的方向。在下面的示例中,你会看到角色一直在追赶一个黄色的球(不幸的是永远追不到!哈哈)。

以下是效果,以及相关的蓝图设置和目标偏移 GIF:

Unreal+Engine%2FblogAssets%2F2017%2FSEPTEMBER+2017%2FThe+Occupation+Animation+Tech+Blog%2FIMG6_PieceOfCandySet-770x223-be0a1732766d1d33c4c9e3ab2882745a0351a344

Unreal+Engine%2FblogAssets%2F2017%2FSEPTEMBER+2017%2FThe+Occupation+Animation+Tech+Blog%2FIMG7_PieceOfCandySet_2-770x211-e0d79bd178843175c1f2cd5a130df762bcc13341

Unreal+Engine%2FblogAssets%2F2017%2FSEPTEMBER+2017%2FThe+Occupation+Animation+Tech+Blog%2FGIF8_WalkLeansAimOffset-ec813037004b2ac7b6e013c0ad0a6fc92253f623

[行走倾向目标偏移]

以上就是在《The Occupation》中使用的完整运动系统了。下面是该设置的最终动画图形,以及用我们的运动系统和 UE4 默认设置经过的路线对比视频。

Unreal+Engine%2FblogAssets%2F2017%2FSEPTEMBER+2017%2FThe+Occupation+Animation+Tech+Blog%2FIMG8_AnimGraph-770x390-e9a679c94be1f88c5a2c671f1bd5edef3bc387cd

Unreal+Engine%2FblogAssets%2F2017%2FSEPTEMBER+2017%2FThe+Occupation+Animation+Tech+Blog%2FIMG9_AnimEventGraph-770x297-2e54738a785f965abcb9e89e97150f681b663480

希望该博客对您有用,如果有任何问题或评论,请在下面留言,还可以通过 Twitter (@whitepapergames) 或电子邮件 [email protected] 与我们联系。