关于Unity中旧版动画系统的使用

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 = -1;
 animation["run"].layer = -1;
 
 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里面设置了默认动画状态的代码。

posted @ 2017-07-30 16:56  杭者  阅读(1914)  评论(0编辑  收藏  举报