AdvanceLocomotionSystem总结
前言
本文再次对ALS进行一个总结, 重点看动画状态机部分, 数据结构和计算部分不重点关注
本文含有大量动图, 加载比较慢
骨骼分层与动画叠加
ALS的一大特色就是基于基础动作及Pose,通过叠加、混合等方式实现基础动作的复用和灵活的扩展, 同时用骨骼分层结合大量曲线来控制不同身体部位的混合情况
一般的动画叠加
上面就是多数情况我们使用的动画叠加方式
+ =
如果按照上面所示简单暴力的叠加, 那么结果很奇葩, 下面我们看一下ALS的实现方案
MakeDynamicAdditive
ALS并没有大量的把动画序列改成Additive模式,而是程序化的生成叠加数据, 这里保存了局部空间和模型空间的2个叠加数据缓存
骨骼分层
以左手臂举例
通过曲线Layering_Arm_L
来选择是使用默认动画还是使用叠加动画(ALS里这条曲线非0即1)
再通过变量ArmLAdd
(从曲线获取)来选择是使用单帧动作还是叠加上基础运动动画
上图两个几乎完全一样的节点区别是使用局部/模型旋转
翻译成人话就是如下
看一下效果
当然, 如果按照传统的方式也能做出来, 只不过不论是逻辑还是资源方面都没啥优势
再举个例
+ =
上图所展示的是基础单帧Pose + 走路动作 = 最后的动作
+ =
上图所展示的是双手持手枪单帧Pose + 走路动作 = 最后的动作
什么变化?
我们看到手臂的颜色是白色的,这里代表着手臂使用了另外的方式参与了全身动画的实现
颜色说明:
红色:完全叠加
白色:使用单帧动画
黑色:不使用分层动画(即使用基础层的动画,这里暂时没有)
+ =
上面所展示的是双手持步枪单帧Pose + 走路动作 = 最后的动作
什么变化?
左手是粉色的,意味着左手叠加了一部分基础动作
下面我们来对比一下叠加与否的效果
手臂使用单帧Pose动作,其余叠加上基础层的运动数据
右手叠加上基础层的运动数据
ALS的方案,右手稍微叠加了一点运动数据
测试一下蒙太奇的播放, ALS本身没有换弹动作,借用其他项目的动作测试(动作本身不匹配)
可以看到左手可以正常播放蒙太奇动画,但是无法正确保持Aim角度,这是因为ALS的ArmSlot
在Aim处理的外层,这是问题
其他动画叠加测试
- Epic初始射击动画包
- Mage动画包
- TwoHandSword动画包
ALS没有单独的上半身分层, 而是拆开了左右手臂, 有些时候反而不太方便, 如果有需要可以单独加一个上半身分层
另外Rootmotion动画播放时需要视情况在蒙太奇动画里设置相应的曲线, 可以参考ALS的Roll动画
分层状态机
- 一张图概括所有状态机分层
Locomotion Cycles层
实现了8方向的移动, 以及移动Lean效果的叠加
关注点
- 六变形的状态机
- RB和LB实际上是过渡节点, 目的是完成pelvis的转向
- ALS的一个小技巧: 45度的移动在刚开始使用了两个方向的混合动作, 但是逐步的会单独使用F/B的动画结合角色的旋转来实现
缺陷
如上图, LF到B的过程, 因为没有单独的pelvis翻转动画, 导致腿部有明显的穿帮现象, 同样的也会出现在RF到B的过程
Locomotion Detail层
实现起步的动画叠加效果
ALS没有起步动作, 即通过混合完成Idle->Run的过程, Walk -> Run 的过渡中叠加了一个上图所示的动作
对比一下叠加前后的区别
Locomotion States层
实现停步和循环转身动画, 这里我们重点讲一下停步
实现停步比较复杂, 需要关注下面几个技术点
- 脚步曲线
- IK锁脚
- 停步动画
脚步曲线
ALS通过曲线设定是否有脚踩到地面, 或者哪只脚更靠近地面
有些简单的实现方案会使用动画通知来设定当前是哪只脚落地, 但并没有考虑两脚都腾空的情况
IK锁脚
IK锁脚需要根据脚步曲线来分2种情况
- 有脚踩到地面
- 双脚腾空状态
停步动画
如果右脚踩地
那么播放左图动画, 结合动画曲线来控制脚步IK (ALS 脚步IK计算较为复杂,这里暂不具体展开)
如果双脚腾空但是右脚靠近地面
那么同样播放右脚踩地动画, 同时右腿快速混合至左图的单帧动画
演示
Ground层
Ground层主要做了一件事, 即 姿势切换
关注点
状态切换中间加了管道保护,判定当前没有Action执行的时候才进行姿态跳转
States层
最外层的状态机,用于切换姿势,后期扩展游泳/攀爬等可以放到这里
- ALS用一个来自角色设置的bJump来判定是Falling还是Jump
- 落地以后根据速度和输入情况叠加了下蹲姿势
对比一下
FootIK层
虚拟骨骼
- ALS使用了很多虚拟骨骼来辅助计算TwoBoneIK
ik_foot
骨骼用于锁脚VB_foot_offset
作为TwoBoneIK的效应器VB_foot_target
用于判断脚步是不是距离期望位置有偏差, 如有就播放单脚过渡动画(看上去像把这只脚收回来)- ALS的移动动画的
ik_foot
骨骼都有数据, IK效应器的位置计算依赖此骨骼的位置信息, 所以在此方案下无法使用UE4自带的移动动画, 理论上有替代方案, 额外的VB? 否则需要对动画制作提出要求
设置FootIK
ALS在Ground层直接通过ModifyCurve
开启了FootIK, 部分动画比如攀爬动作通过曲线动态开启/关闭FootIk
Ragdoll层
进入Ragdoll
执行顺序
- 修改移动状态为None
- 状态机进入Ragdoll(播放Flail动画)
- 设置碰撞
- SetAllBodiesBelowSimulatePhysics
- 停止当前蒙太奇
- 根据模型位置持续设置当前Actor的位置(图中的胶囊碰撞是渲染问题,真实的胶囊体跟随着角色)
退出Ragdoll
- 保存当前快照(SnapShot)
- 恢复移动状态
- 播放起身动画(根据pelvis朝向)
- 恢复碰撞
- 恢复物理效果
- 基于快照混合至其他动画层
攀爬
检测
- 向前射线检测,检查前方是否有角色无法直接走上去的障碍物
- 从上一个碰撞点上方向下进行射线检测,并确保该碰撞位置角色能行走
- 检查攀爬点是否有足够空间容纳胶囊体,如果有则将该位置设为目标变换(Target Transform)并且计算障碍物相对高度(Mantle Height)
- 通过当前的Movement State以及障碍物高度决定攀爬的类型
- 传递参数,开始攀爬(Mantle Start)
攀爬
- 将世界坐标系中的攀爬目标的Transform转换成以障碍物Component为基准的局部坐标系
- 初始化攀爬目标(Mantle Target)和攀爬实际偏差量(Mantle Actual Start Offset)
- 初始化攀爬动画偏差量(Mantle Animated Start Offset)
- 设置Timeline,关键是让Timeline的长度和曲线实际长度(曲线总长减去起点位置)相同, Timeline的PlayRate和动画的PlayRate也必须相同;设置完毕后,开启Timeline
- 从预设曲线中获取XYZ的Alpha值做插值计算(ALS这里用了4个lerp)
演示
相机系统
一个没有动画的动画蓝图
主要做了如下几件事
- 自定义CameraManager代替默认第三人称模板的SpringArm+Camera的方式
- 重写BlueprintUpdateCamera
- CameraManager挂载骨骼模型相机,创建动画蓝图,用曲线来控制相机位置信息