UE5.8 动画压缩与重定向:让小怪物跳起骑士的舞蹈
1. 小队的窘境:一套动作,三种骨架
老陈的独立项目里有一支三人小队:人类骑士格雷、绿皮兽人塔克、还有一团永远保持微笑的史莱姆波波。策划希望他们能共用同一套剑盾动作库,原因是预算有限,美术没有时间给每个角色单独手 K 一百多段动画。
格雷的骨架是标准的 UE5 Mannequin,四肢比例匀称。塔克肩膀更宽、手臂更长,手指骨数量还多两根。波波没有明确的四肢,躯干是一堆柔软的骨骼链,骨盆位置几乎贴着地面。把同一套骑士挥剑动画直接拖到三个角色身上,场面一度非常尴尬:格雷的动作刚健有力,塔克的手肘反折到身后,波波则像一块被风吹动的果冻,盾牌直接插进了自己的脸里。
问题的根子出在两个地方。第一,原始动画数据量很大,不做压缩内存会爆炸。第二,三套骨架的骨骼层级、比例、休息姿势都不一样,必须先把动画重定向到目标骨架,才能谈得上共用。UE5.8 把这两件事整合进了一条相对顺畅的管线,本文就沿着这条管线往下走。
architecture-beta
group raw[原始资源]
service mocap[动捕数据] in raw
service handkey[手K动画] in raw
group engine[UE5 处理管线]
service compress[动画压缩] in engine
service retarget[IK 重定向] in engine
service runtime[运行时采样] in engine
group output[输出]
service skeletal_mesh[骨骼网格] in output
mocap:B --> T:compress
handkey:B --> T:compress
compress:B --> T:retarget
retarget:B --> T:runtime
runtime:R --> L:skeletal_mesh2. 动画压缩到底在压什么
动画序列在磁盘上通常由逐帧的旋转、位移、缩放曲线组成。假设一段奔跑动画有 帧,骨架有 根骨骼,每根骨骼每帧需要存储一个四元数旋转和一组三维位移,原始数据量轻松超过几十 MB。手游包体里如果塞进去几百段这样的动画,玩家还没进游戏就已经被下载体积劝退了。
压缩的本质是在可接受的视觉误差范围内,用更少的采样点和更低的数值精度来表示这些曲线。可以把误差写成一个简单的约束:
这里 和 是第 帧第 根骨骼的原始旋转与位移,带帽子的是压缩后的近似值, 表示四元数之间的角距离, 是项目允许的最大误差。只要每一帧、每一根骨骼的误差都小于阈值,肉眼通常就很难分辨。
UE5 里常用的压缩思路分成三类:
- 逐帧有损压缩:降低旋转或位移的数值精度,去掉对视觉影响不大的高阶信息。
- 关键帧重采样:只在姿势变化剧烈的帧保留关键帧,平缓区间用线性或曲线插值。
- 基于统计/学习的压缩:利用大量动画数据的统计特征,构造更紧凑的表示,比如 ACL 插件。
下面介绍三种在具体项目中经常碰到的算法。
2.1 Additive 动画
Additive 并不是严格意义上的位级压缩,它解决的是复用问题。开发者可以把一段差异动画叠加到基础姿势上,例如“头部受伤后仰 15 度”或“持枪瞄准时的肩部抬起”。基础姿势和 Additive 差异可以分别压缩,差异曲线通常变化范围小,数值精度可以压得更狠。
在项目中,老陈把骑士的 idle 呼吸做成 Additive,基础姿势用普通压缩,叠加层用更低的采样率。这样在 的存储比例下,肉眼没有看出区别。UE5 的 AnimInstance 里通过 Apply Additive 节点把差异混合到最终姿势,运行时开销很低。
2.2 FACS 面部编码
FACS(Facial Action Coding System)把人脸表情拆成若干 Action Unit,例如眉头上扬、嘴角下拉、眼睑闭合。每个 AU 是一个 0 到 1 的权重,运行时再把权重映射到 Blend Shape。对于 MetaHuman 这类高面数角色,直接用 FACS 驱动比逐帧存储全脸骨骼曲线省得多。
UE5.8 对 FACS 工作流做了增强, Sculpt 刷、镜像目标、权重锁定这些功能让美术能在引擎里直接修 Blend Shape。老陈虽然做的是兽人和史莱姆,没有用到人脸,但他把史莱姆的蠕动拆成了六个“身体 AU”,用曲线权重控制不同区域的起伏,思路完全一样。
2.3 ACL:Animation Compression Library
ACL 是 Nicolas Fournier 主导的开源压缩库,后来以插件形式集成到 UE5。它的核心想法是把一段动画看成一条时空曲线,用球面插值和误差驱动的关键帧选择来逼近原始数据。ACL 通常在相同误差下比 UE 自带压缩小 10% 到 30%,解压速度也更快。
ACL 的代价是需要为每个平台单独测一遍误差。对于移动平台,老陈会把 Max Pos Error 设为 0.1 cm、Max Rot Error 设为 0.25 度;在主机上则可以放宽到 0.5 cm 和 1 度,因为大屏幕距离和动作幅度会掩盖微小抖动。
flowchart TD
A[导入原始动画] --> B{目标平台与角色类型}
B -->|PC / 主机 / 高精度角色| C[优先 ACL 或自动]
B -->|移动 / 风格化 / 远景| D[Additive + 低精度]
C --> E[设置 Max Pos Error / Max Rot Error]
D --> E
E --> F[烘焙并对比原始与压缩曲线]
F -->|误差超过阈值| E
F -->|通过| G[进入 IK Retargeter 或直接使用]3. UE5 的动画压缩设置
在内容浏览器里双击任意 Animation Sequence,Details 面板里有一组 Compression 设置。老陈第一次打开时会被一堆参数吓到,其实日常只需要关注几条。
Compression Algorithm 决定用哪套压缩器。默认的 Automatic 会在内置算法里挑一个,项目如果装了 ACL 插件,也可以手动指定 ACL。手动指定的好处是同一类资产有稳定的误差上限,方便批量检查。
Translation Compression 和 Rotation Compression 分别控制位移和旋转的编码方式。旋转通常用四元数的最高精度选项,位移如果骨骼本身很短,可以用较低精度。Scale 曲线在大多数角色里不变,直接勾选 Remove Trivial Scale Keys 能省不少空间。
Max Pos Error 与 Max Rot Error 是误差天花板。数值越小,文件越大;数值越大,越可能看到抖动或滑步。老陈的测试方法很朴素:把阈值拉大,看角色身上哪里先出现 artifacts,再把该区域的误差收紧,其余骨骼保持默认。
Additive Anim Type 在 Additive 资产里必须正确填成 Additive Type,否则叠加节点会拿到错误的基础姿势。UE5 支持 Local Space Additive 和 Mesh Space Additive 两种,前者适合局部细节,后者适合需要跟随世界方向的表情或受伤反馈。
Force Root Lock 会把根骨骼锁定在原点,适合原地循环动画;需要根运动的 locomotion 则要关闭,否则角色会在原地跑步。
项目设置里还有 Per-Platform Overrides。主机端可以用更高的采样精度,移动端则允许更大的误差。老陈在 Android 包体里把位移误差放宽到 0.3 cm,旋转误差放宽到 1.5 度,包体减了 18%,战斗场景里没人看出区别。
4. 骨架重定向:让三种比例共用一套动作
动画序列在 UE 里绑定到一个 Skeleton 资产。Skeleton 不仅记录骨骼名字和层级,还保存了最初生成它时的网格比例。当塔克和波波想借用格雷的动画时,直接复用 Skeleton 已经不够,必须进行重定向。
4.1 同一 Skeleton 不同比例
如果三个角色共用同一个 Skeleton 资产,只是身体比例不同,UE 提供了简单的 Bone Translation Retargeting 选项。在 Skeleton Editor 的骨骼树上,每根骨骼可以设为 Animation、Skeleton 或 AnimationScaled。
- Animation:位移直接来自动画数据,不做任何调整。适合根骨骼或需要精确位置的末端骨骼。
- Skeleton:位移完全使用目标骨架绑定姿势里的长度。适合身体中段,避免长腿角色被压短。
- AnimationScaled:把动画里的位移按目标与源骨架的骨骼长度比例缩放。
缩放比例就是:
是目标骨骼长度, 是源骨骼长度。这个模式最常用,它既保留了动画的相对运动,又适配了目标角色的腿长和臂长。老陈把塔克的四肢都设成 AnimationScaled,躯干用 Skeleton,根骨骼用 Animation,基础移动立刻变得正常。
4.2 不同 Skeleton 需要 Rig
波波的情况更麻烦。它的骨架层级和格雷完全不同:没有明显的锁骨,手臂是触手状骨骼链,腿只有两根骨头模拟弹跳。UE 自带的同 Skeleton 重定向已经无能为力,必须引入 Rig 资产。
Rig 是一个抽象的中间层,它定义了“头、颈、脊柱、手臂、腿”这些语义链,而不是具体的骨骼名字。源 Skeleton 和目标 Skeleton 都挂载同一个 Rig 后,动画数据先从源骨骼映射到 Rig 链,再从 Rig 链映射到目标骨骼。这个过程就像先把中文翻译成世界语,再翻译成英文,前提是两种语言都能表达相同的意思。
graph LR
subgraph source[源骨架 格雷]
S_R[根]
S_P[骨盆]
S_S[脊柱]
S_A[手臂]
S_L[腿]
end
subgraph rig[抽象 Rig]
R_P[骨盆链]
R_S[脊柱链]
R_A[手臂链]
R_L[腿链]
end
subgraph target[目标骨架 波波]
T_R[根]
T_P[骨盆]
T_S[软体脊柱]
T_A[触手]
T_L[弹跳腿]
end
S_R --> R_P
S_P --> R_P
S_S --> R_S
S_A --> R_A
S_L --> R_L
R_P --> T_R
R_P --> T_P
R_S --> T_S
R_A --> T_A
R_L --> T_L5. IK Retargeter 工作流
UE5 的 IK Retargeting 系统把 Rig 的概念进一步工程化,变成了 IK Rig 和 IK Retargeter 两种资产。前者描述单个骨架的链结构,后者把两套 IK Rig 连起来并执行重定向。
老陈的操作顺序如下:
- 给格雷创建 IK Rig,把脊柱、左右手臂、左右腿、头部分成独立的 Retarget Chain,并设置骨盆为 Pelvis。
- 给波波创建 IK Rig,把柔软的触手和弹跳腿也划分成对应的链。链的名字最好和格雷保持一致,UE 会自动做模糊匹配;不一致就要手动指定 Source Chain。
- 创建 IK Retargeter,Source 选格雷的 IK Rig,Target 选波波的 IK Rig。
- 在 Retarget Pose 里把两个角色摆成一致的姿势。格雷是 A-pose,波波也要临时掰成 A-pose,否则手臂角度会整体偏掉。
- 在 Asset Browser 里双击源动画预览效果,调整 Chain Mapping 和 Op Stack 里的参数。
- 满意后批量 Export Selected Animations,生成绑定到波波骨架的新 Animation Sequence。
sequenceDiagram
participant S as 源角色 IK Rig
participant R as IK Retargeter
participant T as 目标角色 IK Rig
S->>R: 发送骨骼链定义
T->>R: 发送对应链定义
R->>R: 匹配骨盆 Pelvis 与根运动
R->>R: 对齐 Retarget Pose
R->>R: 执行操作栈 Op Stack
R->>T: 输出目标骨架姿势
R->>R: 预览源动画并批量导出IK Retargeter 的优势在于它支持不同骨骼数量、不同命名、不同朝向的骨架。UE5 Mannequin 和 MetaHuman 之间就自带一套预置的 RTG_UE5Mannequin_To_MetaHuman, indie 团队可以直接把 Mannequin 动画库搬到 MetaHuman 上。
Op Stack 里常见操作包括 Copy Bone、Retarget Chain、FK/IK 切换、Pelvis Motion、Floor Constraint 等。老陈的经验是:先把每条链用默认的 Retarget Chain 跑通,再对脚部和骨盆加 Floor Constraint,最后处理手指和触手末端。末端骨骼数量不一致时,可以取消映射,让它们在目标绑定姿势里保持原样,避免触手乱飞。
6. 重定向里的常见病
即便管线搭好,预览窗口里依然会出现各种诡异现象。老陈把问题分成三类:滑步、扭曲、比例失调。
6.1 滑步
滑步最常见的原因是根运动没对上。源动画里角色向前跑了 cm,目标角色腿更长,步幅更大,如果直接拷贝根位移,脚就会在地面上漂移。修复办法有几种:
- 在 IK Retargeter 里开启 Stride Warping,根据腿长比例自动缩放步幅。
- 把腿部链改为 IK 模式,脚跟着地时强制贴合地面。
- 导出后手工修根运动曲线,让位移增量与目标角色的步频匹配。
老陈给塔克用了 Stride Warping,把他的步幅系数调到 ,滑步基本消失。
6.2 扭曲
扭曲通常来自休息姿势不一致。格雷是 A-pose,波波默认是蜷缩姿态,直接重定向会让手臂绕肩关节翻转 90 度。解决办法是在 Retarget Pose 面板里把波波掰成和格雷一致的 A-pose,并保存为 Retarget Base Pose。如果已经保存了还是扭,可以检查 Chain Mapping 里的骨骼朝向,必要时加 Rotation Offset。
脊柱扭曲也很常见。源角色有三节脊柱骨骼,目标角色只有一节,重定向时旋转会被平均分配,导致腰部像麻花。老陈把波波的软体脊柱拆成更多骨骼,并用 Copy Bone 逐个绑定,扭曲才缓解。
6.3 比例失调
比例失调包括手臂过长、手够不到剑柄、头埋进胸口等。它的数学表现是链长度比 与动画幅度不匹配。塔克的剑比格雷长 20%,如果只是缩放手臂,握剑点还是偏移。老陈的做法是给武器单独做 Socket,握持时用 IK 把右手锁定到 Socket,左手做辅助对齐。这样武器动画和角色动画解耦,重定向只负责身体,握持由 IK 保证。
flowchart TD
A[预览重定向结果] --> B{出现哪种 artifact}
B -->|脚在地面上滑动| C[检查根运动与 Stride Warping]
B -->|手臂或躯干螺旋| D[对齐 Retarget Pose 并检查骨骼朝向]
B -->|手够不到道具或肢体比例异常| E[加 IK 约束或调整链长度比]
C --> F[再次预览]
D --> F
E --> F
F -->|仍有问题| B
F -->|通过| G[批量导出]7. 内存与加载优化
动画压缩只解决了磁盘和内存中的数据大小问题,运行时还要考虑加载时机和采样开销。老陈在手机上测试时发现,关卡里同时刷出十二个敌人后,帧率会周期性掉一下。Profiler 显示瓶颈不是渲染,而是动画采样和姿态混合。
一条简单的经验是:不要把所有动画都塞进默认加载组。UE5 支持把 Animation Sequence 放到 Streamable Asset 里,按关卡或敌人种类异步加载。远处的小怪只需要 idle 和 run,近战攻击动画可以等玩家靠近再加载。这样做能显著降低一次性内存峰值。
姿态混合的开销和骨骼数量成正比。如果某些敌人距离摄像机很远,可以用 Bone LOD 或 UAnimInstance::SetBoneFilter 跳过手指、面部、披风等细节骨骼的采样。老陈给远景敌人关闭了手指和面部曲线,采样开销降了约 40%。
Additive 动画虽然省空间,但运行时要额外做一次姿势叠加。把多个 Additive 链合并成一条 Additive,或者把常驻的呼吸、瞄准偏移直接烘焙到基础动画里,可以减少每帧的混合次数。
重定向本身也有开销。运行时通过 Retarget Pose From Mesh 节点做实时重定向,适合主角和少数精英敌人;普通小兵最好在内容浏览器里先 Export Retargeted Animation,把重定向结果烘焙成新的 Animation Sequence。烘焙后的资产在运行时和普通动画一样快。
内存预算可以用下式估算:
是动画类别数, 是同时驻留的该类动画数量, 是单帧单骨骼压缩后字节数, 是帧数, 是参与采样的骨骼数。老陈用这个公式把同时驻留动画从 80 段压到 35 段,内存占用从 187 MB 降到 94 MB。
下面是一段在 DefaultEngine.ini 里启用 ACL 并设置全局默认误差的示例:
[/Script/ACLPlugins.ACLAnimBoneCompressionCodec]
+DefaultErrorThreshold=(MaxPosError=0.1,MaxRotError=0.25,MaxScaleError=0.01)
bSkipBone=0
[/Script/Engine.AnimBoneCompressionSettings]
+Codecs=/Script/ACLPlugins.ACLAnimBoneCompressionCodec实际项目中建议先在几条代表性动画上跑 Compress Animation 命令,对比文件大小和曲线误差,再把参数写进 ini。
8. UE5.8 的新改进
UE5.8 在动画和绑定这块加了大量工具,跟压缩和重定向直接相关的有三点。
第一,Foot Definition Options for Retargeting。重定向时脚部的定义不再只有一套默认规则,可以为不同比例和风格化角色指定脚跟、脚趾、脚掌的相对位置。塔克这种脚掌特别宽的兽人角色,重定向后脚掌能正确贴合地面,而不是悬空或者插进地里。
第二,Retarget Override Sets。同一套 IK Retargeter 可以保存多组覆盖配置,每组覆盖可以修改操作栈属性、启用或禁用某些操作。老陈给主角和 NPC 分别建了一个 Override Set:主角保留高精度 IK 和手指链,NPC 关闭手指映射并放宽骨盆约束。切换时不需要复制 Retargeter 资产,直接在节点或变量里选 Set 就行。
第三,变量与 Anim Curve 绑定。Override Set 里可以声明蓝图变量,也可以在运行时把动画曲线值绑定到重定向属性。例如角色手持武器时,一条 IsHoldingWeapon 曲线可以动态调整手臂 IK 权重,重定向结果会随状态自然过渡,不用在 AnimBP 里写复杂的分支。
除了这些,UE5.8 还新增了自动化烘焙、Control Rig Physics Beta、Control Rig Dynamics 和 Direct Mesh Controls。这些工具主要面向绑定和镜头修形,和压缩重定向不在同一条管线,但能让动画资产的生产效率整体提高。
9. 结尾
老陈最后用了一周时间把骑士、兽人、史莱姆的动画管线跑通。格雷继续用原始动作,塔克通过 AnimationScaled 和 Stride Warping 解决了比例和滑步,波波靠 IK Retargeter 把触手和身体链映射到了骑士动画上。三套角色共用同一份动作库,美术只做了少量 Additive 修正和武器 Socket 对齐。
动画压缩和重定向不是一次性开关,而是一组需要反复测量的参数。先用压缩算法把数据量控制住,再用重定向把姿势适配到不同骨架,最后用 Profiler 验证运行时开销,才是比较稳的做法。UE5.8 把重定向的覆盖配置和脚部定义做得更细,独立团队也能在不用写大量自定义代码的前提下,做出多角色共用动画的方案。
希望这套思路能帮你在自己的项目里少踩几个坑。