动画性能

自动关联目录:动画性能

1. 定位

动画的成本在两个地方:CPU 侧求值(AnimGraph + IK)与内存侧(动画数据的解压与驻留)。大世界里,同屏角色数一多,这两项都会先于渲染成为瓶颈。

一句话定位:动画优化的第一刀是"减少需要完整更新的角色",第二刀才是"简化单个角色的图"。

2. 三层优化

① 更新频率:URO(Update Rate Optimization)——不是每个角色都每帧更新
② 求值成本:AnimGraph 简化、LOD、骨骼 LOD、IK 开关
③ 内存与解压:动画压缩、流式、共享

3. URO(更新率优化)

URO 让远处的、不重要的角色降低动画更新频率(如每 3 帧更新一次,中间帧复用上一次的结果或做插值)。

相关说明
EnableUpdateRateOptimizations(Skeletal Mesh Component)开启 URO
AnimUpdateRateTick相关 CVar 分组
a.URO.*URO 的各类参数
bEnableUpdateRateOptimizations组件上也可设

启用 URO 是同屏大量角色时收益最大的一档,且视觉代价通常很小。

4. Animation Budget Allocator

UE 的 Animation Budget Allocator 插件:给整体动画预算设上限,动态分配每个角色的更新率,保证总耗时不超预算。

要点说明
适用大量 NPC / 群体场景
机制按"重要性"(屏幕占比、距离)分配更新率
代价远处角色动画精度下降

它比手工配 URO 更省心,代价是需要调参与验证视觉。

5. 骨骼 LOD 与动画 LOD

机制作用
骨骼 LOD(Skeleton LOD)远处减少参与解算的骨骼数
动画 LOD按距离切换到更简单的 AnimBP/图
网格 LOD 联动网格 LOD 下降时同步降动画精度

骨骼 LOD 对 IK 与 Transform Bone 节点收益明显——骨骼少了,遍历就少了。

6. 并行与多线程

机制说明
多线程动画更新更新与求值放到工作线程(见 AnimBP)
并行求值a.ParallelAnimEvaluation 一类开关
退化的代价一旦在线程安全函数里访问 UObject,整条链退化到游戏线程

最大的隐性陷阱:以为开了多线程,实际上因为某处 Cast 而退化——用 stat anim 与 Insights 确认。

7. 参数与控制台变量

CVar / 设置作用
stat anim动画耗时统计(第一步)
showdebug animation显示当前 AnimBP 状态与 URO 情况
a.URO.Enable / a.URO.*URO 参数
a.ParallelAnimEvaluation并行求值
a.ParallelUpdate并行更新
Animation Budget Allocator 插件设置预算分配
Skeletal Mesh 的 bEnableUpdateRateOptimizations组件级 URO
骨骼 LOD 设置Skeletal Mesh 资产里配置

8. 代价与权衡

手段收益代价什么时候不该用
URO收益最大远处动画不连贯主角、近处角色不该降
Budget Allocator自动控总预算需要调参角色数少的场景不必
骨骼 LOD减少解算量远处骨骼精度下降需要精确 IK 的近处角色不适用
动画 LOD简化图要维护多套简单角色不必
动画压缩省内存与带宽解压 CPU + 误差见 动画压缩与内存
共享动画(动画库/实例化)省内存复杂度—

9. 踩坑与排查

坑现象怎么验证
没开 URO大量 NPC 时动画耗时高stat anim 看更新数量
以为多线程实际退化动画占游戏线程检查线程安全函数里是否访问 UObject
骨骼 LOD 没生效远处依然全骨骼解算检查骨骼 LOD 配置
IK 全角色全时开求值慢远处/非必要应关(见 IK)
AnimGraph 重复求值慢Cache Pose(见 AnimGraph)
主角也被降频主角动画不连贯URO/Budget 应排除主角
动画数据太大内存高见 动画压缩与内存
只测了一个角色上线后群体卡顿必须压测同屏角色数

10. 排查顺序

1. stat anim → 更新耗时 vs 求值耗时
2. 角色多?→ URO / Animation Budget Allocator
3. 单角色慢?→ AnimGraph 复杂度、IK、Transform Bone
4. 占游戏线程?→ 是否退化(线程安全约束)
5. 内存高?→ 动画压缩与骨骼 LOD
6. 一定要压测:同屏 N 个角色,而不是只测一个

参考