距离匹配的效果可以参考这篇我的个人项目开发日志中的视频演示:
距离匹配,Distance Matching,是一种游戏逻辑驱动动画的动画播放方式,主要用于停步动画,根据玩家的预期移动距离,播放对应距离的动画。这种播放方式可以确保不论玩家的实际速度如何,只要停步动画本身的 Root Motion 是正确的,就可以播放最佳的停步动画。对于玩家操作反复起步停步的情况,也能有不错的动画表现。
(所以我的视频里有些停步动画有滑步现象,是因为原始第三方资产的动画就有相对 root 的滑步问题,我还没来得及处理。资产正确的情况下,例如拔刀状态的慢跑停步是有比较好的表现的。)
其工作流大致如下:
A. 设置移动参数:
首先,你需要确定玩家移动组件上的基础数值。如果这些数值后续发生变化的话,我们的动画资产不一定能有最佳的匹配结果。对于停步动画,你需要关注下列参数:
(Last Updated Velocity 是个运行时变化的参数,但主要受影响于你使用的移动模式的速度上限)
B. 测量停步位移曲线:
上一步的图中,我们看到的蓝图函数 Predict Ground Movement Stop Location,是 Epic 提供给我们的函数(需要启用 Animation Locomotion Library 插件)。它会根据上述的参数,预测玩家在不发生其他位移影响(例如玩家输入)的情况下,还有多少距离就会彻底停下。这个预测结果会被动画蓝图读取,并匹配最佳的停步动画播放进度。这样的预测结果,每次玩家单纯停下移动输入后,在没有其他影响的前提下,都会是一致的。所以如果我们能获得这个预测结果曲线,并且根据这个曲线调整我们的动画和相关的参数曲线,我们就能让动画蓝图匹配到最佳的播放结果。
测量这样曲线的方式有很多种,你可以实际记录每次玩家停步时每一帧的位移,然后存储成某种你喜欢的数据格式,也可以逆向工程 Predict Ground Movement Stop Location 函数的算法,直接自己计算从最高速度开始的停步位移曲线。我采用了前一种方法,使用 Sequencer 录制测量停步位移曲线,并且我是在角色蓝图里直接调用了 Predict Ground Movement Stop Location 这个函数,记录的这个函数的输出值,确保获得最准确的预测值。用 Sequencer 记录还有一个好处,这个曲线可以复制粘贴到其他的 Unreal 的曲线编辑器里,包括动画序列的动画曲线中,方便进一步编辑或导出动画数据进行编辑。
C. 调整动画和参数:
有了上面那段停步位移曲线,下一步就是调整动画。
如果你还没开始制作停步动画,那就把上一步测得的曲线复制粘贴到你的 Root 节点的运动上,然后以此为基础开始制作你的停步动画。你可以在曲线达到终值后继续做动画的剩余部分,例如混合到 Idle 的部分等,只要 Root 在之后保持不动。
在你制作完自己的停步动画并且导入引擎后,或者如果你已经有了停步动画,但是你的停步动画本身没有 Root Motion,那么在其上新建一个名叫 Distance 的曲线,然后把上一步的曲线复制粘贴过去,然后在 Y 轴(曲线值轴)上平移这个曲线,让这个曲线的终值为 0。
如果你已经有了停步动画并且有 Root Motion,那么可以使用动画修饰器 DistanceCurveModifier 自动从你的停步动画中抽出 Distance 动画曲线,这个修饰器会把你的 Root 关节的运动变成 Distance 曲线。
接下来,你可以根据你的动作节奏调整这个 Distance 曲线。简单地来说,动画蓝图会比较实际的预测停步距离和你这个曲线里的值,播放动画的时候,从你这个动里匹配这个曲线值和实际值最接近的一帧。所以如果你的 Distance 曲线和上一步测出来的实际的停步位移曲线越接近,你的停步动画就会以越接近 1:1 的速度播放。如果你是完全按照上一步测出来的曲线制作的动画,你就能保证在任何情况下你的停步动画几乎都是完美播放的。
D. 在动画蓝图中应用距离匹配:
这一步就是最简单的,你需要用 Sequence Evaluator 播放你的停步动画,并且为其增加一个 On Update 函数绑定。
函数的内容就如下如图所示,大概的意思是指,当我们的预测停步距离还不为 0 的时候,我们进行距离匹配,播放最合适的姿势。当我们的预测停步距离为 0 的时候,我们就从当前位置开始按照正常速度播放动画剩下的部分直到结束。
综上,其实我们可以发现,距离匹配并不严格要求以预测停步距离匹配播放动画。我们可以根据其他的方式自定义有不同含义的曲线,匹配曲线的值播放动画。感觉这会是一个后续值得探索的思路。
Comments