Unity 动画系统采用状态机,将每一个动画视为一个状态,根据用户的输入来改变状态机中的条件,利用该特定的条件来控制状态的切换,从而实现动画的改变。下面将从四个步骤来展示动画系统的使用方法。
在Project中新建一个Animator Controller,将其赋给角色身上的Animator组件。 打开Window->Animator窗口,将动画(Animation)拖放到窗口中,产生动画状态。 设置动画状态间的过渡及过渡参数,注意取消勾选Has Exit Time。默认情况下动画间的过渡是勾选Has Exit Time的,表示一个动画播放结束完自动播放过渡后的动画。由于我们设置了过渡参数,当条件符合过渡时,才实现一个动画到另一个动画的过渡,因此这里不需要勾选Has Exit Time。 用代码控制动画状态间的过渡。 using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerCtroller : MonoBehaviour { private Animator anim; private void Start() { anim = GetComponent<Animator>(); } private void Update() { if(Input.GetButtonDown("Vertical")) { anim.SetBool("Run", true); } else { anim.SetBool("Run", false); } } }在这个阶段中,我们实现向不同方向跑的动画,包括向左、右转弯跑和向前跑。
设置动画状态、动画过渡及过渡参数。 编写代码。 using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerCtroller : MonoBehaviour { private Animator anim; private void Start() { anim = GetComponent<Animator>(); } private void Update() { anim.SetBool("Run", false); anim.SetBool("RunLeft", false); anim.SetBool("RunRight", false); if (Input.GetKey(KeyCode.W)) anim.SetBool("Run", true); if (Input.GetKey(KeyCode.A)) anim.SetBool("RunLeft", true); if (Input.GetKey(KeyCode.D)) anim.SetBool("RunRight", true); } }这种方法可以实现按住不同的键,角色向不同的方向跑动,但是在跑动过程中会发现一个问题,不同方向跑动切换过程中角色会经历一个站直的过程,这使得动画看起来不连贯。 为什么动画会不连贯呢,因为向左跑、向前跑和向右跑之间没有直接的过渡动作,他们都需要通过Idle这个状态作为中转,导致角色必须经过站直,然后才能实现不同方向的跑动,为了解决这个问题,需要在不同方向奔跑的动画状态中加入直接过渡。
Any State表示任何状态,表示动画系统中当前层中的任何一个状态,可以用它来完成不同方向奔跑动画切换的连贯性。
设置动画状态、过渡及过渡参数。 编写代码,这里由于过渡参数没有改变,代码不需要调整。 这里仍然会发现有一些问题,角色跑动的时候会卡顿卡顿的,这个需要调节动画过渡中的混合时间比例,本篇文章不做阐述。这个部分用Blend Tree来实现角色向不同方向跑动的动画。
在Animator 窗口中,右键->Create State->From New Blend Tree,创建一个混合树。进入到Base Layer->Blend Tree中,在Inspector面板中按+号,增加三个Add Motion Field,分别给三个Motion Field赋予Run,RunLeft和RunRight动画。 用鼠标调节Animator窗口中Blend的值,可以在Inspector面板的预览窗口中看到角色动画的改变。 在Base Layer中,将动画状态Blend Tree改名为RunTree,将参数Blend改名为RunTree。增加Idle到RunTree状态的过渡,用Run参数控制。修改代码。 using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerCtroller : MonoBehaviour { private Animator anim; private void Start() { anim = GetComponent<Animator>(); } private void Update() { anim.SetBool("Run", false); if(Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.D)) { anim.SetBool("Run", true); float dir = (Input.GetAxis("Horizontal") + 1) / 2; anim.SetFloat("RunTree", dir); } } }动画系统的Curve 动画系统的Events
