zoukankan      html  css  js  c++  java
  • 关于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里面设置了默认动画状态的代码。

  • 相关阅读:
    MySQL索引
    《深度探索C++对象模型》笔记——Data语意学
    《深度探索C++对象模型》笔记——Function语意学
    近期的bug常见[从以前的零散笔记中整理]
    一个小trick
    3月9日-日记
    第一次考试_心得
    第一次考试_笔记
    哈希笔记
    Dp刷版笔记
  • 原文地址:https://www.cnblogs.com/HangZhe/p/7259606.html
Copyright © 2011-2022 走看看