总览
角色动画到生产后,单纯播放资产通常不够。你会遇到 IK、瞄准、转身、根骨偏移、左右手复用、交互对齐、Root Motion 修正等问题。UAF 把这些程序化修正拆成 Control Rig Trait、Warping Trait/AnimNode 和 Mirroring Task,统一进入 Update/Evaluate/EvaluationVM 管线。
源码依据
重点文件:
UAFControlRig/Internal/ControlRigTrait.hUAFControlRig/Public/ControlRigTask.hUAFControlRig/Internal/AnimNextControlRigHierarchyMappings.hUAFWarping/Private/SteeringTrait.hUAFWarping/Private/StrafeWarpingTrait.hUAFWarping/Private/OffsetRootBoneTrait.hUAFWarping/Private/OverrideRootMotionTrait.hUAFWarping/Private/AnimNode/UAFWarpToTargetNode.hUAFMirroring/Public/MirroringTask.hUAFMirroring/Internal/MirroringTraitData.h
Control Rig Trait
FControlRigTraitSharedDataBase 保存 Control Rig 执行所需的大量配置:
- 输入 Trait handle。
ControlRigSkeleton- 是否重置输入姿态到初始。
- 是否传入输入姿态和曲线。
- 是否从 Mesh 设置初始 transforms。
- 本地/全局空间传递。
- EventQueue。
- InputMapping / OutputMapping。
- 暴露变量名、Control 名、Control 类型和默认值。
- LatentProperties 和对应内存布局。
UE5.8 有 legacy FControlRigTraitSharedData,也有 FControlRigTraitSharedData_v2,后者用 FControlRigAssetStrongReference 引用资产。TControlRigTraitBase 实现 IEvaluate、IUpdate、IHierarchy、IGarbageCollection,实例数据里持有 UControlRig 和 TSharedPtr<FAnimNextControlRigTask>。
Control Rig Task
FAnimNextControlRigTask 继承 FAnimNextEvaluationTask。参数结构 FAnimNextControlRigTaskParams 包含:
bResetInputPoseToInitialbTransferInputPosebTransferInputCurvesbSetRefPoseFromSkeletonbTransferPoseInGlobalSpaceEventQueueInputMapping/OutputMapping- DebugDrawInterface
- ControlRigVariableMappings
- HierarchyMappings
UControlRig* ControlRig- ComponentTransform
bConsumesPreviousPose
这意味着 Control Rig 真正执行发生在 EvaluationVM 任务中,而不是 Update 阶段直接改骨骼。
Warping
UAFWarping 覆盖几类常用修正:
| Trait/Node | 作用 |
|---|---|
FSteeringTrait |
根据目标朝向给 root motion attribute 添加程序化 delta |
FStrafeWarpingTrait |
朝向/平移 warping,包含 spine bones、foot data、IK foot mode |
FOffsetRootBoneTrait |
用根骨偏移吸收 mesh component 移动差异,支持 Accumulate/Interpolate/Release |
FOverrideRootMotionTrait |
Replace 或 Additive 覆盖 root motion delta |
FUAFWarpToTargetNode |
AnimNode 风格,将 root bone transform warp 到目标 root bone transform |
FOffsetRootBoneTraitSharedData 很值得注意:它区分 translation mode 和 rotation mode,并提供 smoothing time、max error、速度 clamp、on ground、teleport threshold、reset on teleport 等参数。这是生产里处理 code-driven movement + root motion blend 的关键。
Mirroring
UAFMirroring 用两个参数结构描述镜像:
USTRUCT(BlueprintType)
struct FUAFMirroringTraitSetupParams
{
GENERATED_BODY()
UPROPERTY(EditAnywhere)
bool bShouldMirror = true;
UPROPERTY(EditAnywhere)
TObjectPtr<const UMirrorDataTable> MirrorDataTable = nullptr;
};
USTRUCT(BlueprintType)
struct FUAFMirroringTraitApplyToParams
{
GENERATED_BODY()
UPROPERTY(EditAnywhere)
bool bShouldMirrorBones = true;
UPROPERTY(EditAnywhere)
bool bShouldMirrorCurves = true;
UPROPERTY(EditAnywhere)
bool bShouldMirrorAttributes = true;
};
FAnimNextEvaluationMirroringTask 会从 VM keyframe stack 弹出顶部 keyframe,镜像后再推回去。缓存里保存 bone mirror map、reference pose rotations、rotation corrections、compact pose map,并按 SkeletalMesh 和 MirrorDataTable 判断是否有效。
项目落地
推荐修正链顺序:
- 原始资产或 Motion Matching 输出。
- Strafe/Steering 根据运动意图修正方向。
- Offset Root Bone 处理 code-driven movement 与 root motion 的差异。
- Control Rig 做 IK、手部贴合、瞄准、武器约束。
- Mirroring 用于左右侧复用动作。
- 最后统一输出和调试。
示意:
Selected graph
-> Motion Matching / Sequence
-> Steering or Strafe Warping
-> Offset Root Bone
-> Control Rig
-> Mirroring
-> Output Pose
使用案例:锁定目标近战攻击
近战锁定目标通常同时需要转向、根骨对齐、手部 IK 和左右手复用。UAF 可以把它拆成可开关的修正链:
Attack graph
Sequence or Motion Matching result
Steering: face target
Override / Offset Root Motion: absorb movement error
Control Rig: weapon hand, offhand, spine aim
Mirroring: left/right attack variant
Output
落地步骤:
- gameplay 或 Ability 系统写入
TargetTransform、bHasLockTarget、AttackSide。 - AnimGraph 选中攻击图后,先播放原始攻击资产,不开修正,确认基础动画正确。
- 打开 Steering,让角色朝目标方向修正 root motion 或朝向。
- 再打开 Offset Root Bone,处理 code-driven movement 和动画 root motion 的偏差。
- Control Rig 只做必要的手部和脊柱约束,不要把整套角色 rig 每帧全量执行。
AttackSide为 left 时启用 Mirroring,复用右手攻击资产。
验收标准:每一层都能单独关闭。关闭 Control Rig 时攻击仍能播放;关闭 Warping 时只丢失对齐质量,不应该导致图崩掉;关闭 Mirroring 时能回到原始右手资产。
使用案例:第三人称瞄准
瞄准链路比近战简单,适合先试 Control Rig:
- UAF 公共变量写入
AimAlpha、AimTargetWS、WeaponStance。 - Chooser 根据
WeaponStance选上半身图。 - LayerStack 只让
UpperBody接收瞄准图。 - Control Rig Trait 读取 target,驱动 spine、clavicle、hand IK。
- AimAlpha 从 StateTree 或 Ability 写入,不由 Control Rig 自己决定。
这个案例能验证 Control Rig 映射、变量传入、层混合和性能,风险比 Motion Matching 小。
架构分析:程序化修正的顺序
| 顺序 | 放什么 | 原因 |
|---|---|---|
| 1 | 原始资产、BlendStack、Motion Matching | 先得到基础 pose 和 root motion |
| 2 | Steering / Strafe Warping | 方向修正应早于手部 IK |
| 3 | Offset Root Bone / Override Root Motion | 处理 component movement 和 root motion 差异 |
| 4 | Control Rig | 基于已经修正的身体姿态做 IK/约束 |
| 5 | Mirroring | 复用左右侧动作,或在最终 keyframe 上应用 |
| 6 | Output / Debug | 输出前记录关键修正量 |
如果顺序错了,常见现象是脚 IK 先算完又被 root motion 改掉,或者镜像后 Control Rig 仍按原侧控制名写入。
调试清单
- Control 名、变量名、类型是否和 Control Rig 资产一致。
- Warping 输入 Transform 是 world、component 还是 local,是否和 UAF 变量一致。
- Offset Root Bone 的 teleport threshold 是否覆盖闪现、拉拽、网络校正。
- MirrorDataTable 是否和当前 SkeletalMesh 匹配。
- 每个修正层是否有 LOD 开关和性能统计。
常见坑
- Control Rig 映射需要验证变量、Control 名称和类型,资产改名后必须刷新。
- Warping 的输入空间要统一,尤其是 world/component/local transform。
- Offset Root Bone 的 teleport threshold 不合适会导致传送后角色根骨残留偏移。
- Mirroring 依赖
UMirrorDataTable和当前 SkeletalMesh;骨架不匹配会出错。 - 程序化修正不要无限叠加。每层都要能单独关闭、调试和测性能。
源码路径索引
UAFControlRig/Source/UAFControlRig/Internal/ControlRigTrait.hUAFControlRig/Source/UAFControlRig/Public/ControlRigTask.hUAFWarping/Source/UAFWarping/Private/SteeringTrait.hUAFWarping/Source/UAFWarping/Private/StrafeWarpingTrait.hUAFMirroring/Source/UAFMirroring/Public/MirroringTask.h