动画系统Animator
动画类型
Legacy 基础的动画
Generic 动画,包含动画状态机
Humanoid 人形动画,包含动画状态机
Update Mode
Normal 动画播放将与Update同步更新,动画播放的速度与当前的TimeScale相匹配,如果TimeScale变慢,动画播放速度也会变慢
Animate Physics 动画播放将与FixedUpdate同步更新,即与物理系统绑定在一起。当使用物理交互来驱动物体运动时,使用此模式。
Unscaled Time 动画播放将与Update同步更新,动画播放的速度与当前的TimeScale无关,不管TimeScale变成多少,也会以原来的动画播放速度播放动画。
FixedUpdate与Update
FixedUpdate不受帧率变化的影响,以固定的时间间隔来调用。
而Update由于要渲染大场景或计算复杂逻辑,每帧的时间间隔是不一样的。
正常在Unity的设置Time的Fixed TimeStep为0.02,理论上每秒的帧数是1 / 0.02 = 50帧,假设游戏进行比较复杂的逻辑运算,在每帧里消耗了大量时间,导致最后Update只调用了30次,也就是每秒只有30帧,而FixedUpdate依然是50次调用,保持在50帧。
Culling Type
Always Animate 总是播放的,即使在屏幕外也不会被禁用
Cull Update Transforms 当不可见时,动画重定向,IK(Inverse Kinematics)即反向动力学,和Transform的写入都被禁用
Cull Completely 当不可见时,动画系统被完全禁用
Based on Renderers(只在Animation老动画系统中可选) 当不可见(不被渲染)时,动画系统被禁用
IK(Inverse Kinematics)即反向动力学
即可以使用场景中的各种物体来控制和影响角色身体部位的运动,一般来说骨骼动画都是传统的从父节点到子节点的带动方式(即正向动力学),而IK则倒过来,由骨骼子节点带动骨骼父节点,具体情况比如人物走路踩到了石头就需要由脚的子节点来带动全身骨骼做出踩到石头的响应。IK可以使人物和场景更加贴合,从而达到更加真实的游戏效果,如果大家玩过《波斯王子》或《刺客信条》系列,应该对主角的攀爬和飞檐走壁的能力印象深刻,这些都是应用了IK,使动画贴合到具体的场景中进行的表现。
动画转换
int,float,bool,Trigger四种参数类型。
- Trigger类型,本质上跟bool是一样的。但Trigger会执行完毕后,将状态设置为取反状态。如果默认为false,那么执行true之后,会将Trigger重置状态为false。
- 通过判断state.normalizedTime >= 1.0f,来确定当前是否已经完成播放。
- 在实际开发中,随着角色动画越来越多,靠连线Make Transition指向一个新的动画,会变得非常复杂。直接调用m_Animator.CrossFade("anm_dwarfHero_jump", 0.0f, -1, 0f)来播放动画。设置最后一个参数为0.99f(设置为1,会回到开始),可以设置动画到最后一帧。
动作融合 AvatarMask
Avatar Mask允许你丢弃的一些动画数据,只允许某些部位的动画起作用。
当我们需要上半身播放开枪的动画,下半身在播放跑步动画。
- 在Animator系统中,在BaseLayer中拖入跑步动画,
- 新建一个Layer,并为其创建一个AvatarMask,取消下半身的IK控制,同时,设置Layer的weight为1,表示覆盖BaseLayer的动画, 然后在新建的Layer中,拖入开枪动画。
- 就可以完成上半身和下半身不同动作的融合了。
动画重定向 Retarget
人形模型在设置动画类型为Humanoid时,可以复用动画Controller。解决不同骨骼间,复用动作的问题。解决方案:将不同的骨骼映射到Unity中的一套标准骨骼中。
动画重定向技术就是一种时间换空间的思路,在运行时将一套动画根据预计算好的骨骼差异信息,得到目标模型骨架上可以适用的动画数据,就可以生成目标角色的动画效果。
重定向技术就是一种在将动画数据从一个骨骼拷贝到另外一个骨骼的过程。
假设我们想让一个female的模型复用一个male的动画:
a) 导入male的模型,设置动画类型为Humanoid,设置好Avatar上的骨骼映射关系;
b) 导入male的动画文件,设置其类型为Humanoid,讲其Avatar设置为male的avatar;
c) 使用male的动画制作一个Animator;
d) 导入female的模型文件,设置动画类型为Humanoid,同样设置好Avatar上的骨骼映射关系;
e) 可以拖拽一个模型文件到Scene中,然后把它的Animator设置为之前male的动画制作的Animator,即可看到Retargeting之后的效果了。
动画重定向遇到的问题记录
在使用过程中,我们遇到了一些问题。
1. 第一个是角色的武器或者飘带在使用Humanoid类型的动画系统之后不会移动了,或者移动的位置有了很大的偏差。这时候可以在动画文件的属性设置里,查看Mask下的Transform选项,里面可能存在没有被勾选的骨骼。我们目前的做法是把Transform下的所有骨骼对象都勾选上。
2. 某些角色在重定向之后的动画中表现为脚不贴地,和地面之间有缝隙,原始动画中没有这一问题。设置T-Pos的姿势,这里我们可以对参考姿势做微调。
Animator Override Controller:
- 是 “Animator Controller”的重载, Animation Controller可以认为它就是动画状态机, Animator动画系统是通过Animator Controller来控制动画播放的,里面存着指向各个动画片段Animation Clip的引用,和播放动画的逻辑,比如状态转移等.
- 而Animator Override Controller则用于拓展一个已存在的Animtor Controller,它只是在后者基础上可以在某些状态播新的动画Clip,保持后者的状态机逻辑,结构
- 应用方面,Animator Override Controller能做到一个状态机(Animator Controller)实现多套动作,非常利于维护。
- 按官方说法就是:如果一类模型可以共用动画状态机,则可以弄一个基础Animtor Controller,里面是基本的动画状态逻辑,然后给某个模型使用就弄一个Animtor Override Controller,然后把其中不同的动画Clip换成自己的,这样就只需维护一份动画状态机了,省心省力。比如NPC系统的各个NPC。许多怪物也可以共用。
Blendtree混合树
1. 状态转移和混合树,虽然两者都是用来制作平滑动画,但区别很大
2. 状态转移是从一个动画状态平滑转移到另外一个动画状态
3. 动画混合树是把多个动画混合起来, 将角色不同的部分混合,对一个部分而言,是混合所有动画中该部分的动作,形成该部分的新动作,是混合动画。
Bake Into Pose属性,根骨骼动画
- 在引入模型时,模型附带的Animation信息,Root Transform Position/Root Transform Rotation的Bake Into Pose(烘焙在动作中)属性,作用是是否将根骨骼的位置和旋转,烘焙到动作中,如果应用了这个属性,根骨骼的位置改变或旋转,只会影响它本身,而不会影响它在世界空间中的真实位置或旋转。
- 如果不应用这个属性,动画就是根骨骼动画,将会用Animation动画本身所带的位置或旋转,来驱动角色的位置或旋转,从而影响它在世界空间中的真实位置或旋转。
- 角色idle动画,不需要根骨骼动画;带有位移的动画,可以采用根骨骼动画。
- 注意:要想使用根骨骼动画,在Animator 组件上,需要勾选Apply Root Motion。
- 在代码中,可以接管根骨骼动画的位移,实现MonoBehaviour的OnAnimatorMove()方法。
Sprite序列帧动画
当Sprite是由一帧帧的贴图组成的,可以选择Sprite Mode为Multiple,在Sprite Editor中Slice切分成多个Sprite,选中需要做成动画的Sprite,拖到场景中,Unity会自动生成序列帧动画的Animator Controller和Animator Clip。
UV动画——本质通过改变贴图
UV动画,主要用于序列帧、模拟无限重复的背景让模型顶点对应的UV随时间变化,使其对应纹理像素不断随时间变化但是无法达到让物体“变形”的效果。UV动画是一种常用的渲染技巧,经常用来描述水的流动、霓虹灯的闪烁等。实现的原理就是动态修改贴图的UV坐标,使物体表面产生变化。
顶点动画——本质通过改变顶点坐标
顶点动画,原理和UV动画有相同的地方,但是顶点动画可以让物体动起来的同时,达到变形的效果其主要原理是在 顶点着色器中对模型的顶点进行偏移,再将偏移后的顶点位置输出到片元着色器中。与改变mesh顶点不同的是,在gpu中更改顶点信息的效率远高于在cpu中改变mesh的数据。这种渲染技巧普遍用于模拟自然界物体波动,如水流、草地、火焰等效果。
Animator的性能优化
性能瓶颈:状态机,动作融合,IK
优化:
- 限制Animator的数量,在移动端超过30个,对CPU压力比较大
- 关闭根骨骼动画
- 限制骨骼数量(<=30)
- 采用Base On Render,但是从屏幕外进入屏幕的动画,不能选择这种模式
- 控制动作的帧数,一般30fps
- 用Animator,尽量用Generic,不用Humaniod
- 尽量用Animation!!!