总览
Motion Warping 的参数很多,但可以按三个问题拆:要不要改平移?要不要改旋转?动画里哪个点代表对齐点?先回答这三件事,再看细节。
平移参数
| 参数 | 含义 | 建议 |
|---|---|---|
bWarpTranslation |
是否修改位移 | 大多数对齐动作开启 |
bIgnoreZAxis |
是否不改 Z | 平地攻击开,攀爬/跳跃慎开 |
bWarpToFeetLocation |
对齐脚底视觉根而不是 Actor 原点 | 角色胶囊/mesh 有偏移时常用 |
AddTranslationEasingFunc |
原动画没位移时添加位移的缓动 | 只做兜底,不要依赖它做长距离移动 |
平移最常见的问题是 Z 轴。平地攻击如果不忽略 Z,目标点地面高度轻微不同就会让角色上下浮。攀爬和跳跃如果忽略 Z,角色可能永远到不了平台高度。
旋转参数
| 参数 | 含义 | 使用场景 |
|---|---|---|
bWarpRotation |
是否修改旋转 | 面向敌人、面向交互物 |
RotationType Default |
匹配目标旋转 | 坐下、开门、落点朝向固定 |
RotationType Facing |
朝向目标位置 | 近战、交互看向目标 |
RotationMethod Slerp |
平滑插值 | 默认首选 |
SlerpWithClampedRate / ConstantRate |
限制旋转速度 | 防止突然扭头 |
Scale |
按窗口比例缩放旋转 | 需要严格结尾对齐 |
UE5.8 把旧的 OppositeDefault/OppositeFacing 标为废弃,建议用 AdditionalRotationOffset 做 180 度或其它最终偏移。
Warp Point
EWarpPointAnimProvider 有 None、Static、Bone。它回答的是:动画内部哪个点要对齐目标。很多人误以为目标永远是 root。其实你可以指定动画里的一个骨骼或静态点作为对齐参考。
例如翻越动画里,如果要让手抓边缘,可以用 Bone 方式选择手部或辅助骨骼作为 Warp Point;如果只关心角色最终脚底落点,可以不提供 Warp Point,直接让 root/feet 对齐。
bSubtractRemainingRootMotion
这个参数的意思是把 Notify 后剩余 root motion 从目标里扣掉,让角色在动画结束时到达目标,而不是 Notify 结束时到达目标。适合窗口提前结束但后面还有少量收尾位移的动画。初学建议先关掉,等你能解释“目标是窗口结束点还是动画结束点”后再开。
使用案例:平地重攻击
推荐:Warp Translation = true,Ignore Z = true,Warp Rotation = true,RotationType = Facing,RotationMethod = SlerpWithClampedRate,最大旋转速度给一个保守值。窗口从踏步开始到命中前结束,命中后不要继续转。
使用案例:跳到平台
推荐:Ignore Z = false,目标 Transform 用平台落点,窗口覆盖起跳后到落地前。注意距离限制:如果目标高度差太大,动画姿态会被拉得不自然,这时应该用不同高度动画或 Motion Matching/Traversal 选择。
常见坑
- 目标朝向和角色朝向差 180 度,却用废弃的 Opposite 类型。
- 攀爬开了 Ignore Z,角色水平对齐但高度错。
- Actor 原点对齐了,脚底却悬空,因为胶囊半高和 Mesh offset 没处理。
- 窗口结束点和动画结束点混淆,
bSubtractRemainingRootMotion被随手开关。 WarpRotationTimeMultiplier太小,角色瞬间转向。
源码依据
URootMotionModifier_Warp 保存平移、旋转、Warp Point、剩余 root motion 和附加旋转等配置。EMotionWarpRotationType 在 UE5.8 中保留 Default 和 Facing,旧 Opposite 值标为 Deprecated。EMotionWarpRotationMethod 提供 Slerp、限速 Slerp、ConstantRate 和 Scale。EWarpPointAnimProvider 决定 Warp Point 来自静态 Transform 还是骨骼。
源码路径索引
MotionWarping/Public/RootMotionModifier.hMotionWarping/Public/RootMotionModifier_SkewWarp.hMotionWarping/Private/RootMotionModifier.cpp