编辑器内创建动画资源的优化
Unity动画系统回顾
- Animation中的Animation Clip
- Animator中的Animator Controller Graph
- Playable API中的Playable Assets
- 其中Animation Clip主要是动画曲线资源。Unity的Legacy动画系统主要依赖于此类资源
- Legacy动画系统主要是对应Unity4之前的动画系统,Unity4后Unity的动画系统改为Mecanim。这套系统中以上三类资源都会用到,其核心是Playable API。在Playable API基础上支持Animation C# Jobs、Timeline等。其中Animation C# Jobs主要是为了Animation Rigging与Kinematica高级动画提供高效的并行基础
上述三类动画资源的使用细节
Animation
- 通过Animation窗口,我们可以创建与编辑游戏对象的各种属性的动画曲线
- 这些属性包括对象的Transform、材质颜色、光照亮度、声音音量以及我们在脚本中自定义的各种值
- 在使用上,Animation也最为简单,但我们需要注意一些性能的细节:
- 播放单个AnimationClip速度,Legacy Animation系统更快,因为老系统是直接采样曲线并直接写入对象的各种属性;而新的Mecanim系统,则具有用于混合的临时缓冲区,并会对采样曲线和其他数据进行额外的复制。请注意,这里的高效是指播放单个Animation Clip,而并不是整体的动画性能老的系统一定比新的系统高,后续会详细说明
- 针对动画的缩放曲线,比位移、旋转矩阵开销更大。因此我们尽量不要做对对象的缩放动画
- 常数曲线不会每帧写入场景,更高效
Animator
- Animator中的Controller对应Animation Controller Graph资源;Avatar是我们在导入时生成设置的
- Animator动画系统更新的主要流程
- 其中白色的步骤是动画系统中各个时段的回调,灰色的步骤则是动画系统更新的关键步骤
- 最开始的是Animation Controller Graph中的动画状态机更新
- 接下来的ProcessGraph是对需要评估的所有Animation Clip进行采样,以及计算根骨动画(RootMotion)
- 再接下来的ProcessAnimation是计算动画图混合结果
- WriteTransform是将所有动画变换从工作线程写入场景对象的Transform
- 最后的WriteProperties是从主线程中将其他动画属性写入到场景对象中
- 了解完新动画系统的更新流程,还需要注意Animator的一些细节:
- 不要使用字符串来查询Animator
- 使用曲线标记来处理动画事件
- 使用Target Marching函数来协助处理动画
- 将Animator的CullingMode(裁剪模式)设置成Based On Renderers来优化动画,并禁用SkinMesh Renderer的Update When Offscreen属性来让角色不可见时动画不更新
对比Animator与Animation
- Animation适合简单动画和较少动画组件的情况,而Animator更适合处理高动画曲线条数和更复杂的动画组件情况
- Animator的弊端可以用Playable API来解决
Playable API
- Playable API是以一套树形结构来组织数据源,并允许用户通过脚本来创建和播放自定义的行为,支持与动画系统、音频系统等其他系统交互,是一套通用的接口
- 换句话说,在Unity中,所有带时间轴的资源,都可以用Playable API来播放
- Unity中还提供了一套可视化PlayableGraph的工具:
PlayableGraph Visualizer
对比Playable API与Animator
PlayableDirector与Timeline Asset的关系
- 可以通过自定义的Track来扩展Timeline的轨道
- 并可以在Timeline轨道上通过Signal或Mark添加自定义的回调事件,这样Timeline工具可作为角色技能编辑器、过场动画编辑器的工具了
总结:解决方案选择
- 一些简单、少量曲线动画可以使用Animation或动画区间库如Dotween\iTween等完成,如UI动画、Transform动画等
- 角色骨骼蒙皮动画如果骨骼较少,Animation Clip资源不多,对动画混合表现要求不高的项目(如开关门、车辆、简单角色)可以采用Legacy Animation。要非常注意控制总体曲线数量
- 一些角色动画要求与逻辑有较高的交互、并且动画资源不多的项目可以直接用Animator Graph完成。这种情况要非常注意动画状态机中的状态机节点个数,避免使用过多的动画状态机节点与层
- 对于动作游戏,对动画混合要求较高、有一些高级动画效果要求、动画资源庞大的项目,建议采用Animator+Playable API扩展Timeline的方式完成(这时状态机中一般只有一个基础节点-走跑跳,而一些特殊的如技能、持不同武器的动画状态模组以及过场动画的表现都使用Playable API去扩展Timeline完成)。