在体验官方的Motion Matching(运动匹配,简称MM)的实例后,感觉这有可能成为未来游戏对Locomotion动画系统的新选择(什么屁话,育碧早就开始用了)。心痒痒的就想着看看能不能用手头的动画素材来复现一下,一是想要从零开始搭建,摸清MM需要怎样的资产进行运作;二是想跟着官方案例走,对MM系统的运作原理做一次摸底。然后就有了这万余字的笔记了。
MM系统引入了很多新内容(至少对我来说确实如此),因此在对MM系统进行复现的同时,还要对新内容进行学习区分,一边了解新内容的工作流程,一边重复测试其对MM系统的作用及必要性。因此想要做短时间内从初识MM到熟练使用MM,需要本身就对动画系统、运动组件、以及动画姿势特征有一定的知识积累;此外,要是有对动画扭曲Animation Warping相关使用经验,就更好了。当然这个只是对操作者的要求,MM系统对动画资产的要求同样不低,而最不可缺少的就是,动画资产需要包含根骨骼运动数据。
当然啦,刚开始学习的我哪知道这个,下了虚幻自带的角色资产之后就开始上手搞了嘛!而结果是还真就搞出来了。从最简单开始,先制作角色的待机与行走状态。MM系统对动画进行混合的流程与传统状态机的类似,只不过是将状态机更换为Pose Search Database(简称PSD,用于存储状态类似的动画资产),将转换条件更换为使用Chooser(选择器表)的
条件Column。我将待机动画归至Idle状态,行走动画归至Jog状态,检测
运动组件Character Movement的速度是否为0来做条件切换该两个状态,成功实现两个动画资产的单独播放。那接下来就是加入起步以及行走结束的动画以实现待机到行走的平滑过渡。
对于传统状态机,两个动作进行混合,可以直接使用机器做插值计算混合,也可以制作混合空间Blend Space,通过调节暴露的参数分配权重来混合,也可以插入对应的过渡动画资产来实现动动画切换。若需要使用第三种方案,就需要添加动画资产并设置过渡条件。MM系统也是如此,但对于以上的第二、第三种方案,在MM系统中可以直接将相应的混合空间或动画资产添加到PSD中,在执行动画更新时经过Chooser的筛选进行播放。由于在判断当前角色处于待机或是行走状态是用速度是否为零来做条件,那按照正常逻辑,当角色处于起步与结束状态时,其速度小于行走速度但不为0,因此应该把起步、行走循环、行走结束的动画放置在同一个PSD中进行检测,然后使用当前速度值对其进行区分。此乃第一个坑。
由于在Chooser进行筛选时,若有多个资产的条件相同,优先选择上层的资产输出,因此在上面的案例中,由于角色起步与结束时速度值范围都处于0到行走速度之间,就会出现在起步时播放结束的动画,或者在结束时播放起步的动画。至此,不难分析得知,对于起步与结束的状态,需要设置更严谨的转换条件。使用速度方向做区分?不行,因为起步与结束时有可能都朝向同一个方向移动。使用当前加速度大小做区分?似乎也不行,跟速度值一样,在某个阶段会处于加速度大小相同的状态?再进一层思考,在起步时,角色将继续加速,在未来某个阶段会达到行走时的速度;而在结束行走时,角色将持续减速直至停止在原地。那有没有一种可能,可以使用未来的速度做区分?
当角色接受输入时,其运动组件会按照设置的方向驱使角色移动,而在得知角色运动的最大速度、加速度,以及地面的摩擦因素等数值前提下,是否能计算出角色在未来某个时间点的位置或速度?简单物理题嘛,肯定是能的。同样的计算,当角色断开输入的瞬间,角色将要停止,同样也可以计算某个时间点角色的位置或时间。那通过预测角色未来某个时间点的速度,对比当前时刻的速度,我们可以判断角色是处于何种阶段:
- 持续为0,角色处于闲置静止状态
- 持续不为0,角色处于连续运动状态
- 当前可能为0,未来不为0,角色处于起步状态
- 当前不为0,未来可能为0,角色处于停止状态
要对角色运动进行预测,则需要添加Pose History节点。该节点能生成预测的轨迹点并存储历史轨迹点。在动画蓝图中添加如此函数,并连接到Event Update Blueprint Animation每帧触发,即可获取基于当前时刻的轨迹Trajectory引用。(*Speed 2D是当前速度在XOY平面上的矢量长度值)
从当前轨迹Trajectory获取未来0.4秒及0.5秒的位置,求取其差值,并除以时间差0.1秒从而粗略计算出未来速度Future Velocity,通过判断当前速度Veloctiy与未来速度Future Velocity,可以判断角色当前的运动阶段。
但官方案例中并不对当前速度Veloctiy与未来速度Future Velocity进行对比,而是计算该两速度在一定范围内是否都不等于0,若是,设置角色状态为Move,否则设置为Idle。当角色处于Move状态,使用Veloctiy与Future Veloctity进行对比,当Future Veloctity与Velocity的差值大于等于100时,说明Velocity还未能接近Future Velocity,设置角色状态为起步(官方案例中是设置Is Starting函数返回值为真,此处为了讲解目的便如此书写罢);当该两个速度差值小于100 时,说明角色将很快达到最大移动速度,即将与行走循环动画做混合。当角色处于Idle状态时,当前角色的平面速度值,若大于20,说明角色将停不停,让角色播放行走停止动画;若小于20,则播放闲置动画。
如上修改后确实能正常播放各个阶段的动画。以下为结果展示