插件用了两颗动画树,Mannequin_AnimBP和Mannequin_IK_AnimBP,前者挂载在人物Blueprint上,用来处理人物主体动画;后者挂载在人物的Skeletal Mesh上,用作动画后处理来实现脚部IK动画。Mannequin_AnimBP动画树大体分为地面动作、空中动作两部分的处理。其中地面Locomotion的表现需求是最多的。
地面Locomotion算是动画树最复杂的状态机了,可以简单分为3层:
可以看到第一层状态机只是对第二层状态机输出动画做了一个呼吸动画的叠加。第二层状态机输出的Idle动画其实是静止Pose,在这一层才统一叠加上呼吸动画。
第二层状态机只定义了几种Locomotion状态的过渡逻辑,可以看到Locomotion有走停转站四种状态。
第三层状态机分别是走停转站的动画实现,其中走(Moving)的实现是最为复杂的。可以看到状态机有很多动画分支,全部是用BlendSpace,以Direction,Gait Value作为输入值来输出移动动画的。在此简单解释Gait Value,插件设计该变量将Walk/Run/Sprint三类状态的速度值映射为[1,3],动画机内只关注跟Walk/Run/Sprint状态相关的Gait Value,无须关注具体速度值。
人物有两种转身模式,一种是根据人物速度方向转身(Velocity Direction Mode),一种是根据镜头方向转身(Looking Direction Mode),这两种转身模式也造就了两种移动模式,通常适用于在ACT/FPS游戏里切换格斗/射击和自由移动两种移动模式。转身模式通过变量ALS_RotationMode控制。
八方向移动
以人物速度方向转身的移动动画比较简单,基本只需要对朝前的Walk/Run/Sprint动画做BlendSpace融合即可。以镜头方向转身的移动动画则要做八方向移动动画,简单的八方向动画(前/后/左/右/左前/左后/右前/右后方向移动)其实用一个BlendSpace就可以实现,但插件做了更复杂的八方向动画。左右移动进一步细分出了左移姿势前进,左移姿势后退,右移姿势前进,右移姿势后退等四个动作,用了两个BlendSpace来实现这种八方向移动。
状态机根据人物移动方向切换使用两个BlendSpace,当镜头与速度方向夹角处于[-90,90]范围内用前进BlendSpace,否则用后退BlendSpace。上图红框部分是两个BlendSpace实际采用区域。
该状态机还有个分支用于输出下蹲移动动作,移动速度是恒定的,所以用了1D BlendSpace做输出,比较简单,不展开细说。
另外整个状态机很多分支都有RF变量身影,该变量意思是移动动画是以左脚还是右脚在前,因此以RF变量可以分出了两种BlendSpace。
移动倾斜
根据Lean Gounded X/Lean Gounded Y变量可以BlendSpace出一个身体向左右,前后倾斜一定角度的Pose,将其与移动动画做融合,就能表现出角色倾斜奔跑的效果。这个融合主要是为了体现角色速度感。角色速度,每帧速度角度变化值决定左右倾斜度,每帧角色速度变化值决定前后倾斜度。
正常停止移动动画
从Moving到NotMoving有两种过渡,一种是正常停止移动的Stop动画,一种是奔跑急停的Pivot动画。Stop动画细分了多种状态下的Stop动画,这里只看普通跑动下的Stop动画。
可以看到Stop动画是由2个BlendSpace输出的,根据左脚在前,还是右脚在前,决定使用哪一个BlendSpace。两个BlendSpace都接收Feet Position X和Feet Position Y作为输入。
Feet Position X:表示Foot Direction,Foot Direction的范围是[-90,90],表示移动方向。
Feet Position Y:表示Foot Position。Foot Position的范围为[-1,1],其中左脚迈到最前时为-1,右脚迈到最前时为1,两腿刚好交叉时为0。看上图可知当Foot Position>0时,即右脚迈在前面时,用ALS_N_Stop_RF BlendSpace,否则用ALS_N_Stop_LF BlendSpace。
Feet Position X、Feet Position Y两个变量值的更新很巧妙:所有的移动Animation Sequence上,都添加了名为FootDirection,FootPosition的Curve,记录了每一帧的脚步位置和移动方向。当进入Stop状态时,通过GetCurveValue接口获取FootDirection,FootPosition的Curve值,再设置给Feet Position X、Feet Position Y。
Stop的BlendSpace基本就是采样了人物在左移,右移,前行3个方向下,左脚或右脚在前的脚步回收动画,可以让人物在停止移动时,有一个明显收住脚部,回撤站立的表现,增强人物运动真实感。
奔跑急停动画
增加奔跑急停的Pivot动画用于人物跑动中大幅度转向的过渡,进一步强化运动速度感。判断移动输入方向与人物移动方向的Yaw角度大于100(基本就是反向移动)时,人物在地面上且速度处于一定范围内,即进入Pivot过渡。
原地转身动画
插件没有在AnimGraph里播放原地转身动画,而是在EventGraph里调用Play Montage接口播放TurnInPlace的Montage动画,在AnimGraph里添加TurnInPlace Slot输出转身动画。
看下动画树的EventGraph里调用转身动画的接口:
决定是否播放转身动画主要靠以下3个变量:
Turning In Place:当前是否正在转身
Turning Right:当前是否正在向右侧转身
Aim Yaw Delta:当前帧镜头朝向与人物朝向的Yaw角变化值
基本逻辑是转动镜头Yaw角大于90度转身或180度转身阈值时,且当前没有在转身,则播放转身动画;当前已在转身中,只可以打断往相反方向转身。这样避免持续往一侧转动镜头时,播转身动画过程中,出现打断动画,重头播转身动画的情况。
转身动画只有腿部动作,不带人物转向,人物转向通过TurnInPlace_AnimNotifyState动画事件每帧设置。
每帧设置转向用一个EaseInOut曲线来控制,获取上一帧跟当前帧的曲线差值,即为当前帧人物转向Yaw角偏移值。
最后,TurnInPlace_AnimNotifyState动画事件还需每帧判断当前人物是否有移动,移动则打断转身动画。
起跳动作
起跳动作用了基础起跳动作,融合BlendSpace,让起跳呈一定程度的Lean倾斜,表现出人物往对应方向起跳的感觉。其中Lean In Air值由跳跃Z轴速度和移动速度决定,Direction为移动速度方向。
下落动作
下落动作有两个阶段动作,一开始是正常腾空下落,随着下降速度变大,逐渐Blend为手脚胡乱摆动的动作,用一个EaseInOut曲线控制Blend速度。
下落动作同样融合BlendSapce做Lean倾斜,并且会计算着地时机,在快着地前融合一个人物手臂上扬再下落的动作,强化落地冲击感。该融合靠Land Prediction Alpha变量控制。该变量在人物下落过程中,每帧以脚部为圆心做球形检测,得出球形与地面的相交最短距离,归一化到[0,1]的范围值来做动画融合。
落地动画
人物跳跃着地后播放一个着地过渡动画,当然如果在此期间人物移动则打断过渡动画。