Animation Pose Snapshot
Animation Pose Snapshot
使用
将角色的当前的姿态保存一份,后续对保存的姿态进行处理。
保存姿势函数:
- UAnimInstance::SavePoseSnapshot(FName SnapshotName)
- UAnimInstance::SnapshotPose(FPoseSnapshot& Snapshot)
使用保存姿势在动画蓝图中用
Pose Snapshot
节点。
过场动画过渡
在播放过场动画结束时,想要角色与过场动画中的动画无缝的过渡,效果如下:

过场动画为简单播放一个跳舞的动画:

示例的具体做法如下:
- 设置
Level Sequence
的Finsh Completion State Override
为Force Restore State
,该设置让过场动画在播放完时,保持角色的姿势。
- 监听过场动画结束,并把角色姿势保存下来,设置混合保存的姿势的开关
- 过场动画通常有跳过功能,手动调用Stop函数停止过场动画,并不能保持角色的姿势,所以这里需要手动再调一下保存姿势的逻辑
- 动画蓝图如下:
Warning
值得注意,经常过场动画中的角色和游戏中的角色并不是公用的一个actor,这里可以是使用UAnimInstance::SnapshotPose(FPoseSnapshot& Snapshot)
方法,存储姿势快照,在同动画蓝图中将Pose Snapshot
节点的Mode
设置为Snapshot Pin
即可
击倒起身
角色在被击倒后开启了物理模拟,进入布娃娃系统后,角色需要从布娃娃姿态播放一个起身动画然后回到待机姿势。由于布娃娃产生的姿态是随机的,所以并不能在起身动画中预设好躺在地面的动画。这里有保存一下播放起身动画前,角色的姿态。将该姿态与起身动画做混合即可,效果如下:

示例的具体做法如下:
- 设置角色物理资源,添加角色的根节点武器配置,并将类型改为运动,关闭碰撞。该设置能让关闭物理模拟时,播放动画角色的位置固定。
- 设置角色物理根节点到骨盆关节的约束,将约束限制都改为自由。
- 按下G键,将角色的骨骼蒙皮开启物理模拟,并将碰撞描述设置为
RagDoll
- 按下F键,将角色当前的姿势存起来,需要Delay一下,然后将角色的骨骼蒙皮关闭物理模拟,播放起身动画。
- 动画蓝图中的设置
同时可以制作:
- 在开启物理模拟时,角色胶囊体跟随骨骼蒙皮的移动
- 根据角色躺在地面上盆骨骨骼的朝向,选择播放正面起身或者背面起身的动画
卡肉
这个没有做示例,简单讲一下实现逻辑,当角色打到敌人时,手臂会有一个被卡在敌人身上的感受,来增加打击感。可以在角色打到敌人时对角色姿势快照,然后将该快照与角色攻击的动画进行按骨骼混合,角色手臂使用快照姿势,其他骨骼使用攻击动画姿势,这样表现出的效果即是手臂会停住一下,大致的动画蓝图设置如下:

原理
数据
struct FPoseSnapshot
{
TArray<FTransform> LocalTransforms; // 骨骼本地空间变换
TArray<FName> BoneNames; // 骨骼名称(可选)
FName SkeletalMeshName; // 骨骼网格体名称
FName SnapshotName; // 快照名称
bool bIsValid; // 是否有效标志
};
骨骼变换存储:
- 使用FTransform数组存储骨骼变换,保持高效的内存布局
- 可以选择存储局部空间或组件空间的变换
性能优化:
- 预分配数组空间避免动态扩容
- 使用内存拷贝批量处理变换数据
线程安全:
- 通常在游戏线程执行
- 快照数据是只读的,可以安全地在多线程环境中传递
保存姿势UAnimInstance::SavePoseSnapshot(FName SnapshotName)
的数据存储在FAnimInstanceProxy::PoseSnapshots
数组中。
应用数据
应用主要使用动画节点PoseSnapshot
实现的文件是FAnimNode_PoseSnapshot
,核心函数是FAnimNode_PoseSnapshot::ApplyPose(const FPoseSnapshot& PoseSnapshot, FCompactPose& OutPose)
,其逻辑就是把快照的每根骨骼的本地坐标数据放到FCompactPose
中。
注意
- 骨骼层次一致性:快照和目标骨骼必须一样
- 性能开销:频繁的快照操作可能影响性能
- 内存使用:大量快照会占用内存
- 曲线数据:默认不包含动画曲线数据,需要额外处理