Unity在5.X以后,有一个旧版的动画系统和新版的动画系统。
新版的动画系统是使用Unity动画编辑器来调的,调动画和控制动画
旧版的动画系统是用其他的第三方软件调好后导出到一个FBX文件里面,就是一个FBX模型文件里面除了模型顶点,数据纹理以外,还有动画信息。美术会把所有与模型相关的动画全部做到一起。
旧版动画系统
1: 导入一个包含多个动画的模型文件;
2: 选中模型文件的Rig---->Animation Type---->Legacy模式
3: 根据美术给出的时间点,来分割动画;
4: Animation组件参数:
(1)Animation 启用自动播放时,播放的默认动画;
(2)Animations 可以从脚本的访问的动画列表;
(3)Play Automatically: 是否自动播放
(4)Animate Physics 动画是否与物理交互;
(5)Culling Type 设置动画的剔除模型: Always Animate总是播放动画, Base On Renders 只有渲染在屏幕上的对象才会播放动画;
Animation组件不是动画,是播放动画的容器,真正的动画是Animation Clip,就是我们剪辑下来的子动画。在Animation组件的Animations属性里面。
代码控制动画的常用函数方法
1: Animation类的Play: 播放指定名称的动画;
2: Animation类的Stop: 停止播放指定名称的动画;
3: Animation类的CrossFade动画融合: 以融合模式来切换动画;
(1) 动画融合能确保动画完美的过渡,两个动作之间不会有突然切换,比较柔和的切换;
(2) 第一个参数下一个播放的名字, 切换的时间间隔, 淡入淡出的模式;
(3)淡出的模式: PlayMode.StopSameLayer 淡入新动画时,只淡出与name同一层的动画,
PlayMode.StopAll 淡入新动画时,淡出所有的动画;
4: 动画混合:
动画混合能消减游戏创建动画数量,让一些动画只应用给身体的一部分,和其它的动画配合一起使用。一个挥手动画,空闲挥手,和行走挥手,如果没有动画混合,就要为这个挥手创建2个动画,一个是空闲的挥手,一个是行走的挥手。
如果有动画混合,只要一个挥手的动画,然后把这个动画和空闲的状态混合,把这个动画和行走的状态混合,就可以得到两个动画。
AddMixingTransform方法进行动画混合;
//例子
先说说Unity3D关于动画方便的东西,Animation Mixing (动画混合),什么是动画混合呢?举个简单的例子吧,一个模型现在又3种动作,分别是idle、walk、shoot,在Unity3D中一个Layer只能播放二种动画,shoot动作只影响左肩膀的骨骼,而不会影响腿部的动作,所有这里就可以把shoot和walk进行Mixing。
function Start ()
{ //增加一个动画剪辑片段 //
animation.AddClip(animation["shoot"].clip, "shootUpperBody");
animation["shootUpperBody"].AddMixingTransform(transform.Find("mover/gun"));
//@parm 路径
animation["shootUpperBody"].AddMixingTransform(transform.Find("mover/roothandle/spine1"));
//设置动画模式
animation.wrapMode = WrapMode.Loop; animation["jump"].wrapMode = WrapMode.Clamp;
animation["shoot"].wrapMode = WrapMode.Clamp;
animation["shootUpperBody"].wrapMode = WrapMode.Clamp; // Put idle and run in a lower layer. They will only animate if our action animations are not playing
animation["idle"].layer = -;
animation["run"].layer = -; animation.Stop();
} function Update () {
if (Mathf.Abs(Input.GetAxis("Vertical")) > 0.1)
{
animation.CrossFade("run");
animation["run"].speed = Mathf.Sign(Input.GetAxis("Vertical"));
}
else
animation.CrossFade("idle"); if (Input.GetButtonDown ("Jump"))
{
animation.CrossFade("jump", 0.3);
}
if (Input.GetButtonDown ("Fire1"))
{
if (animation["run"].weight > 0.5)
animation.CrossFadeQueued("shootUpperBody", 0.3, QueueMode.PlayNow);
else
animation.CrossFadeQueued("shoot", 0.3, QueueMode.PlayNow);
}
5:AnimationState类:可以用来打印当前播放的动画的参数,如动画的名字,长度,已经播放的时间。
6.AmimationEvent类:可以给子动画添加一个事件,就是在动画播放后多少时间time后再自动执行一个事件函数functionName。
播放和暂停
方法一:有些复杂
先播放动画:
animation.Play("Jump");
暂停跳跃动画:
pausetime=animation["Jump"].time;
animation["Jump"].Stop();
继续跳跃动画:
animation["Jump"].time=pausetime;
animation.Play("Jump");
方法二:很简单
先播放动画:
animation.Play("Jump");
暂停动画:
animation["Jump"].speed=0;
继续动画:
animation["Jump"].speed=1;
AnimationClip类
1: events animation clip所有的Animation Events .
2: frameRate Frame rate at which keyframes are sampled. (Read Only)
3: humanMotion Returns true if the animation contains curve that drives a humanoid rig.
4: legacy Set to true if the AnimationClip will be used with the Legacy Animation component ( instead of the Animator ).
5: length Animation length in seconds. (Read Only)
6: localBounds AABB of this Animation Clip in local space of Animation component that it is attached too.
7: wrapMode Sets the default wrap mode used in the animation state.
实例
1.创建Unity工程和文件目录
2.导入资源文件夹player,里面包含FBX文件(里面包含做好的动画信息)和PNG纹理贴图
3.进入Materials文件夹,选择材质球的shader为Mobile---->Diffuse,关联纹理贴图,再把材质球拖进模型中关联
4.查看做好的动画,点击FBX文件,在Animations栏,可以查看动画信息,美术把所有的动画都连在一起,做成一个长动画,是做到同一个轴上的,这个轴上包含了所以帧,可以播放。
5.点击FBX文件,在Rig栏,选择旧版动画模式Rig---->Animation Type---->Legacy模式---->Apply
6.剪辑动画,就是把整个的动画拆分成可以用的子动画,美术会告诉我们哪个动画是从哪一帧开始到哪一帧结束。点击"+",创建新的子动画,“-”删除子动画。
还可以设置播放的次数,是循环播放还是只播放一次---->Wrap Mode---->Loop---->Apply。
7.把模型拖进场景中,会自带一个Animation组件,里面有相应的参数设置,Animation属性里面的内容表示的是启用自动播放时,播放的默认动画。
8.去掉勾选Play Automatically,使用代码来控制动画播放,创建一个脚本anim_test挂载在模型People节点下
打开anim_test
using UnityEngine;
using System.Collections; public class anim_test : MonoBehaviour {
private Animation anim;
// Use this for initialization
void Start () {
this.anim = this.GetComponent<Animation>();
this.anim.Play("idle");//播放idle动画 AnimationState anim_state = this.anim["run"];//AnimationState就是动画的状态
Debug.Log(anim_state.name + " " + anim_state.length + " " + anim_state.time);//打印出当前子动画的名字,长度和已经播放的时间
this.Invoke("stop_anim", 3.0f);//3秒后停止播放动画
} public void stop_anim() {
Debug.Log("stop_anim");
this.anim.Stop();//停止播放动画
}
// Update is called once per frame
void Update () {
if (Input.GetKeyDown(KeyCode.Space)) {//当空格按下的时候执行if中的语句
this.anim.CrossFade("run", 0.5f);//切换当前动画变成run,切换的时间是0.5秒
}
}
}
9.运行,3秒后停止播放动画,期间如果按空格键会切换动画
注意:
动画一般都是设置为循环播放,然后在Update()里面去播放,播放或者切换动画的时候一般都是持续调用Update的满足里面if条件的播放动画的语句,才使得动画可以一直持续循环播放,一旦不满足if条件,就停止播放。
如果是只播放一次的动画,必须要让它成为最后一个要播放的动画,其他动画要想再播放,就必须再满足某个条件。有的时候点击播放一次某个动画,发现只播放到前几帧就停下来或者变成另外一个动画,有可能是因为Update里面设置了默认动画状态的代码。