Unity3d动画系统介绍

发表于2017-12-28
评论0 3.7k浏览

Unity的动画系统非常的灵活强大,动画系统支持动画融合、混合、叠加动画,行走循环的时间同步,动画层,控制动画的各个方面,以及支持基于物理的布娃娃系统和程序动画,下面就带大家来认识下动画系统。


动画类容:

1.了解老版动画(Animation)播放

2.熟悉新版动画的制作

3.熟悉Animator Controller的使用

4.了解动画中的BlendTree(混合树)

5.动画中添加事件和遮罩

6.动画IK(Inverse Kinematics)(反向运动学)


一、介绍(Animation)动画播放

添加  Animation 组件


注意:组件上有  Animations 这个动画列表,一般都会自动加在到里面,如果没有手动拖入;


添加一个  PlayAnim的C#脚本   添加代码如下:

public class PlayAnim : MonoBehaviour {  
    private Animation anim;  
    // Use this for initialization  
    void Start () {  
        anim = GetComponent<Animation>();  
    }  
    // Update is called once per frame  
    void Update () {  
        //播放人物跳跃动画  
        if (Input.GetKey(KeyCode.Space))  
        {  
            anim.CrossFade("jump");//播放动画名为 jump的动画  
        }  
        //播放人物攻击动画  
        if (Input.GetKey(KeyCode.J))  
        {  
            anim.CrossFade("attack1");//我没有讲解CrossFade,可以百度一下  
        }  
    }  
}  


二、熟悉新版动画播放的制作

添加 Animator 组件,在Assets新建一个动画状态机  Animator Controller, 把需要用到的人物动画拖入状态机中,并设置好动画切换的条件

一般有几种状态就设置几个切换值一般常用(Bool)


三、熟悉Animator Controller的使用

控制动画的播放 事例代码

我的 Animator Controller 里面的相关设置


using System.Collections;  
using System.Collections.Generic;  
using UnityEngine;  
public class PlayAnim : MonoBehaviour {  
    private Animator anim;  
    private string lastAnim;  
    private string nextAnim;  
    // Use this for initialization  
    void Start () {  
        //获取当前的动画组件  
        anim = GetComponent<Animator>();  
        lastAnim="Idle";  
    }  
    // Update is called once per frame  
    public void Update () {  
        //连击  
        if (Input.GetKeyDown(KeyCode.K))  
        {  
            ComboAttack();  
        }  
        //控制跑 、跳 、攻击  
        if (Input.GetKey(KeyCode.W))  
        {  
            ChangeAnim("Run");  
        }  
        else if (Input.GetKeyDown(KeyCode.Space))  
        {  
            ChangeAnim("Jump");  
        }  
        else if (Input.GetKeyDown(KeyCode.J))  
        {  
            ChangeAnim("Attack");  
        }  
        else  
            ChangeAnim("Idle");  
    }  
    //播放改变的动画  
    void ChangeAnim(string nextAnim)  
    {  
        //关闭上一个动画  
        anim.SetBool(lastAnim,false);  
        //  
        lastAnim=nextAnim;  
        //播放下一个动画  
        anim.SetBool(nextAnim,true);  
    }  
    //控制连击的方法(比如:连续按三下攻击键,出现三种不同的攻击动画)  
    void ComboAttack()  
    {  
        //把当前动画设为攻击动画  
        ChangeAnim("Attack");  
        //获取当前动画层,右上角的Layers  
        AnimatorStateInfo info=anim.GetCurrentAnimatorStateInfo(0);  
        //如果播放的动画名为 attack1 并且 时间播放时间间隔大于0.5秒;  
        if (info.IsName("attack1") && info.normalizedTime > 0.5f)  
        {  
            //播放第二段攻击动画  
            ChangeAnim("Attack1");  
        }  
        else if (info.IsName("attack2") && info.normalizedTime > 0.5f)  
        {  
            //播放第三段攻击动画  
            ChangeAnim("Attack2");  
        }  
    }  
}  

四、了解动画中的BlendTree(混合树)



在Animator Controller中创建Blend Tree(混合树)

双击进入Blend Tree 可以添加在BlandTree上,其值在[0,1]之间,新加的动画都在[0,1]之间,当blendTree的值在0,1之间变化时,不同的动画播放在切换,

注意:在BlendTree中播放的动画应该把 Loop Time  勾上


五、动画中添加事件和遮罩

在动画播放中的添加一些事件或者改变播放另一动画等的事件处理


上图中 右边的 双击 Take001 在inspection框中有  曲线(Curves) 事件(Events)选项

曲线:

点击曲线,曲线下方有几种默认的曲线形状,就是 X,Y直角坐标系,我们可以在动画方法的时候获取当前点Y轴的数据,传给Animator Controller 中Parameters设置的Float值

,我们可以使用这个Float值进行相关操作,



事件(Events):

在动画播放的时间中,在动画的那一时刻添加事件,下面的值得介绍:Function(方法名)其中可以传入四种值(Float  Int  String  Object);

注意:Object 是在Project下面的游戏物体, 通过 GetComponent<Object> as GameObject 进行 里式转换。

遮罩(Mask):



在Animator Controller中的当前的动画播放层中设置遮罩(Mask) 我这里的AvatarMask01是在Project 面板上建立的 Avatar Mask



在AvatarMask01 的Inspector中可以看到如下图  身体绿色的部分是可以动的,红色的部分是不可以动的,点击绿色的敌方变为红色,我们可以设置两层Layers 来实现遮罩效果,

大体步骤:AvatarMask001把上半身变为红色,AvatarMask002把下半身变为红色,

在第一层中设置Take001的动画并在第一层的Mask中添加新建的AvatarMask001,在第二层中添加新建的AvatarMask002,每层的权重值在(0,1)都改为1,就实现了上半身是播放的第二层动画的上半身,下半身播放的是第一层动画的下半身。



六、动画IK(Inverse Kinematics)(反向运动学)



在Animator Controller中的Layers层动画,在需要使用IK动画的层中把 IK Pass 勾上,下面是一个使用IK动画的例子  前(手没有指向右上的Cube)    后(当按下Space键之后,实现IK动画)


public class IKScript : MonoBehaviour {  
    //是否开启IK动画  
    private bool isActive;  
    //右手上的关注点  
    public Transform rightHadTarget;  
    public Transform leftHandTarget;  
    public Transform rightfeetTarget;  
    public Transform leftfeetTarget;  
    private Animator anim;  
    // Use this for initialization  
    void Start () {  
        anim = GetComponent<Animator>();  
    }  
    // Update is called once per frame  
    void Update () {  
        if (Input.GetKeyDown(KeyCode.Space))  
        {  
            isActive = true;  
        }  
    }  
    public void OnAnimatorIK()  
    {  
        IsIKAnimator();  
    }  
    public void IsIKAnimator()  
    {  
        if (isActive)  
        {  
            //设置IK动画位置偏移的比重值(影响位部,比重值大小(0,1))  
            anim.SetIKPositionWeight(AvatarIKGoal.RightHand,1f);  
            anim.SetIKRotationWeight(AvatarIKGoal.RightHand, 1f);  
            //如果右手目标点不为空  
            if (rightHadTarget != null)  
            {  
                //我们写入IK动画的位置(部位, 目标点的位置)  
                anim.SetIKPosition(AvatarIKGoal.RightHand, rightHadTarget.position);  
                //我们写入IK动画的角度(部位, 目标点的位置)  
                anim.SetIKRotation(AvatarIKGoal.RightHand, rightHadTarget.rotation);  
            }  
            //如果没有目标物体,结尾把动画的比重值设为0  
            else  
            {  
                anim.SetIKPositionWeight(AvatarIKGoal.RightHand, 0f);  
                anim.SetIKRotationWeight(AvatarIKGoal.RightHand, 0f);  
            }  
        }  
    }  
} 


七,unity3d动画设置的介绍






之后就是将动画拖入动画状态机,和在动画机中设置

动画加入动画状态机后,我们需要实现动画间的过渡,动画的过渡需要使用状态机和状态参数实现,目前支持的参数类型有4种(Float 、Int 、Bool、Tigger)


链接:http://blog.csdn.net/leonardo_davinci/article/details/78262879

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引