zoukankan      html  css  js  c++  java
  • Unity3D之Mecanim动画系统学习笔记(八):Animator Layers(动画分层)

    解决什么问题?

    动画分层可以用来解决什么样的问题呢?试想一下如果你要开发一款第三人称的射击游戏,那么肯定是希望身体的动画分为上下两部分,上方根据瞄准的位置和是否射击进行动画播放,下方根据移动播放动画。最好的例子就是Unity4.x自带的示例AngryBots了。

    Avatar Mask

    下面我们就使用Avatar Mask来实现人物在奔跑中招手的效果。

    我们先添加一个人物到场景,同时为其添加一个Animator Controller并设定好跳转条件,如下:

    接下来我们添加下面的脚本来控制动画的播放,对了为了不让角色因为播放动画而移动,记得把“Apply Root Motion”取消,方便我们查看动画播放的效果。

    添加的脚本如下:

    复制代码
     1 using UnityEngine;
     2 using System.Collections;
     3 
     4 public class MaskTest : MonoBehaviour
     5 {
     6     private Animator _animator;
     7 
     8     void Start()
     9     {
    10         _animator = this.GetComponent<Animator>();
    11     }
    12     
    13     void Update()
    14     {
    15         if(Input.GetKeyDown(KeyCode.R))
    16         {
    17             _animator.SetBool("run", true);
    18         }
    19         if(Input.GetKeyUp(KeyCode.R))
    20         {
    21             _animator.SetBool("run", false);
    22         }
    23 
    24         AnimatorStateInfo state = _animator.GetCurrentAnimatorStateInfo(0);
    25         if(state.shortNameHash == Animator.StringToHash("Run") && Input.GetKeyDown(KeyCode.J))
    26         {
    27             _animator.SetTrigger("jump");
    28         }
    29     }
    30 }
    复制代码

    接下来我们希望按下空格时人物播放招手动画,但是跑动跳跃的动画不能停止播放。

    我们需要添加一个新的Layer来管理招手动画的播放:

    同时我们要配置好招手动画,这里的Idle可以不添加任何动画,仅仅表示空就可以了,同时还添加了一个Trigger“wave”表示进入招手动画的条件。

    接下来我们设置一下该层,将其权重设置为1:

    好了,我们修改一下代码试试看吧:

    复制代码
     1 using UnityEngine;
     2 using System.Collections;
     3 
     4 public class MaskTest : MonoBehaviour
     5 {
     6     private Animator _animator;
     7 
     8     void Start()
     9     {
    10         _animator = this.GetComponent<Animator>();
    11     }
    12     
    13     void Update()
    14     {
    15         if(Input.GetKeyDown(KeyCode.R))
    16         {
    17             _animator.SetBool("run", true);
    18         }
    19         if(Input.GetKeyUp(KeyCode.R))
    20         {
    21             _animator.SetBool("run", false);
    22         }
    23 
    24         AnimatorStateInfo state = _animator.GetCurrentAnimatorStateInfo(0);
    25         if(state.shortNameHash == Animator.StringToHash("Run") && Input.GetKeyDown(KeyCode.J))
    26         {
    27             _animator.SetTrigger("jump");
    28         }
    29 
    30         if(Input.GetKeyDown(KeyCode.Space))
    31         {
    32             _animator.SetTrigger("wave");
    33         }
    34     }
    35 }
    复制代码

    运行一下,发现当播放招手动画时其它动画都会停止,该怎么办呢?

    答案是我们需要创建一个Avatar Mask来表示我们只希望播放动画的部分,即手部动画播放,其它部分不播放,在Project窗口右击创建一个Avatar Mask文件:

    将右手部分以外的区别关闭即可:

    这里说一个Transform这个选项,该选项是控制每个骨骼是否参与动画使用的,如果我们的人物有翅膀和尾巴之类的东西就要使用它了。

    最后一步我们将这个Avatar Mask拖入Animator Controller的Wave层中即可:

    再次运行下游戏,我们需要的效果是不是已经出来了呢。

    设置解说

    下面我们来详解一下Layer面板的设置:

    Weight

    动画层的权重,默认的Base Layer必须为1。如果设置为0则当前层的动画不会播放,1则会播放,0-1之间会采用类似融合的情况来播放动画,比如之前的招手的例子,如果设置为0.5则招手动画播放时手部只会抬到脖子附近。

    Mask

    动画遮罩,上方已经详解就不赘述。

    Blending

    动画混合方式:

    • Override:覆盖,表示当前层的动画会覆盖掉其它层的动画,比如招手播放时右手就不能播放其它的动画了;
    • Additive:添加,表示当前层的动画的量添加到其它层的动画,比如招手播放时,手部奔跑或站立的甩动也会保留;

    Sync

    开启了该功能后会多出一些选项,如下:

    我们可以将该功能看做复制的功能。

    Source Layer:指定当前层是哪个层的副本,设定后当前层的状态会和指定层完全一致或完全同步,但是我们可以修改某一个状态的动画。

    该功能提供的效果就是两个状态一致的层可以做出一些不同的调整。

    Timing:当前层和Souurce层同一个状态使用的动画时间长度不一致时,不勾选复制的层按Source层的时间播放(效果就是复制层动画可能会变快或变慢,Source层动画播放速度不变),勾选则Source层按复制层的时间播放(效果就是Source层动画可能会变快或变慢,复制层动画播放速度不变)。

    IK Pass

    表示启动IK动画,上一篇文章已经详解就不赘述。

  • 相关阅读:
    js兼容性——获取当前浏览器窗口的宽高
    pip 换源
    5 二分查找 算法
    顺序查找 冒泡 快排 等
    4 顺序表和链表
    python垃圾回收机制
    3 栈 队列 双头队列
    2 数据结构的性能分析 timeit
    1 时间复杂度
    线程池 爬取一本小说
  • 原文地址:https://www.cnblogs.com/lancidie/p/7345151.html
Copyright © 2011-2022 走看看