10Animation相关
10Animation相关
本文主要记录AnimationComponent相关内容。Animation是Unity最早最传统的动画处理方式。基本上只提供了动画播放相关接口。实际上其还有一部分接口可以用来做一些简单功能。另一方面,对于现在来说,有些简单的动画播放,例如动效部分,也可以简单的通过Animation来实现。
不过另一方面是,Unity提供的最新动画系统是Animator,Animator的推广,以及支持比现在要广泛很多。所以两者都要多了解。
因为并没有源码,这里主要记录各种接口,属性的功能。可以通过这些结构对Animation大概的模型有一定了解。方便后面进行封装。
Animation的很多结构现在看上去官方不在支持。例如button的动画表现也是跟Animator绑定。也就是很多功能关联后续会更多的跟Animator关联在一起。但是Animator本身也有一定问题,可以详见Aniamtor部分。
官方文档地址: https://docs.unity3d.com/2022.3/Documentation/Manual/Animations.html
其中Scripting部分对经典Animation也有说明。
Animation结构


其实简单来说,Animation组件存放了一个默认的Animation Clip以及一个Animation Clip列表。
这些Clip被包进AnimationState这个类型对象中进行存放。同时,这个AnimationState对象,记录了当前Clip播放的状态。
换而言之,就是当Animation播放对应动画的时候,播放时状态会直接记录在对应的AnimationState的实例上面。这个可以通过播放时输出AnimationState的属性来发现。
我觉得可以认为这每一个AnimationState就是一个记录Clip的轨道。对应Clip播放的时候所有关联数据以及状态就是直接记录在AnimationState轨道上的。
下面主要记录Animation上的各种接口效果与含义。
Animation细节
Animation播放的动画主要是Unity自身的.Anim资源。这种类型可以通过Animation Window创建并且key帧。Animator也可以使用.Anim资源,但是两者资源设置上有区别。Animation是经典,老的动画播放系统。为了区分,Animation播放的.Anim资源要勾选Leagacy选项,该选项需要在Debug模式下才能可见。

对于Animation的Play接口主要有三类
- Play
- CrossFade
- Blend
最常用的播放接口。接口使用效果如下。
|
|
从表现来看。当调用Play接口播放时,其运行状态直接记录在对应的AnimationState中。
- 重复调用播放同一个Clip,如果对应Clip在播放中,则不会打断进行再次播放。
- 如果调用播放不同Clip,则根据mode会停止其他动画播放。而对于层的概念则是放在AnimationState的Layer字段上,可以运行时修改。
- 当Layer不同的时候,则不同Clip会同时播放。每个Clip按照各自的进度进行。如果Clip控制不同对象,则各自生效。
- 但是如果播放时,不同Layer的Clip控制同一个物体。只有高Layer的Clip动画效果会生效,但是两个动画的播放状态为都在进行中。相当于一个高Layer覆盖效果。如果希望两个效果可以叠加在一起可以看Blend。
|
|
- Stop接口会停止所有由该Animtion驱动的动画状态。指定名称则停止指定名称的Clip。
- 对于被停止的动画,目标状态会保持在动画被停止时最后一帧的状态。
- 对于被停止的动画,可以再度Play播放,此时动画状态会从Clip的第一帧重新开时。
AnimationState
对于播放时的动画状态可以通过对应的AnimationState来获取。其可以通过Animation的如下接口获取。
|
|
而对于一个AnimationState来说,其主要有一些状态字段。这些字段都是描述当前这一个动画的状态值。
|
|
可以通过修改State对象的属性值来控制动画播放的各种运行时效果。而对于CorssFade,Blend来说AnimationState状态则与其混合效果直接关联。
CrossFade相当于时间维度混合,从动画ClipA过渡到动画ClipB。而Blend则相当于状态空间混合,将动画ClipA和动画ClipB叠加在一起。
CrossFade
|
|
- CorssFade只会将相同Layer的动画向目标动画过渡。换句话说,如果是不同Layer的动画会保持播放。
Blend
|
|
- Blend可以同时播放同一Layer上的多个动画。所有参于动画混合的权重,在作用前都会被归一化。例如两个动画播放权重都为1,实际上相当于某个动画贡献0.5。播放效果还受到AnimationBlendMode参数影响。
AnimationBlendMode.Blend
权重比例混合。实际参于混合动画的所有效果会按照Weight比例混合。相当于
$$E_f=\sum w_iE_i$$其中$E_i$相当于每个动画的左右效果,可能是位移,颜色等等。最终效果则是$E_f$。例如两个动画$A,B$。$A$向右移动200,$B$向上移动200。最终混合后会变成向右移动100向上移动100。需要注意的是最后动画结束时,会使得整个动画结束位置相当于各个动画均匀混合。
AnimationBlendMode.Additive
经过我大量测试,对于Unity创建的Anim资源,Additive模式似乎并不生效。从文档描述来看,应该是可以将目标动画直接以增量的方式叠加到当前动画状态上来执行。
可以AnimationClip资源debug模式中看到,设置当前Clip相对动画。即AdditiveReferencePoseClip以及HasAdditiveReferencePose字段。但是这些设置只针对Animation的叠加模式适用。
最后
作为Unity最经典,也是已经被废弃的动画播放系统。可以看到,Animtion实际只提供了一个Clip播放的功能。可以基于此控件,上面再搭建各种状态混合等结构。但是该系统依然确实很多动画播放功能。用来做简单播放可以,但是想要强大功能还是要另辟蹊径。
Unity后续推出了Animator系统。该系统功能更完善,虽然任然有小的问题,但是该系统可以方便制作更多效果。此外后续Unity还推出了Playable结构,相当于暴漏Animator一些底层API可以做到更加管线化的播放定制。后面以Animator基础之上再添加功能更好。