Unity3D RPG Core | 08 动画控制器

目前我们角色的动画控制器还是使用包里默认的,它是所有动画的循环播放。这节视频会创建我们自己的动画控制器,实现角色静止时会播放待机动画,移动时播放奔跑动画。

1. 准备工作

在创建自己的动画控制器前,我们可以先看看包素材里有哪些动画。点击动画文件,会显示如图 1 所示的内容,上方是默认的模型。

如果我们想要查看当前角色模型的状态,可以点击右上角的“人形”图标,然后选择 Other,接着选择对应的角色模型即可。点击左上角的播放按钮可以播放动画。

图1 人物动画

接着视频中将人物对象生成为预制体。生成的方式为:将原先 Hierarchy 窗体中的人物对象拖拽到 Assets 窗体中;然后界面会弹出图 2 所示的消息,选择 Original Prefab。

图2 创建预制体

目前还不清楚为什么要为人物创建预制体,留作问题。

2. 创建动画控制器

如图 3 所示,我们在 Assets 窗体中选择 Animator Controller,可以创建一个新的动画控制器。

图3 创建动画控制器

创建好新的动画控制器后,我们选择人物对象。将创建好的动画控制器拖拽到 Animator 组件的 Controller 参数下。

图4 指定动画控制器

接着我们双击动画控制器,会跳转到图 5 所示的界面。此时我们创建一个 Blend Tree 状态。

图5 创建 Blend Tree

接着双击 Blend Tree 状态节点,可以进入 Blend Tree 设置界面。

如图 6 所示,Blend Tree 设置界面有三大列。首先在最左侧一列选到 Parameters,右击原先的参数,选择 Delete 将其删除。然后添加一个新的 Float 类型的参数,命名为 Speed

在最右侧一列观察窗口,我们将 Parameter 参数修改为创建的 Speed。然后点击 Add Motion Field 添加三个域,拖拽指定各个域对应的动画,这边分别设置为 Idle、Walk、Run 对应的动画。

其实这边 Blend Tree 的含义是按照 Speed 参数的大小指定动画,即按照人物的速度播放待机、行走或奔跑的动画。我们在图 6 中间一列的节点上,滑动调节 Speed 参数大小,可以看到播放对应不同的动画。

图6 设置 Blend Tree

3. 代码控制

设置好动画控制器中的 Blend Tree 之后,剩下的工作就是传递人物的速度给到 Speed 参数。

我们回到之前写的 PlayerController 脚本。如代码清单 1 所示,首先我们获取人物对象的 Animator 组件(第 13 行)。接着通过 Animator 组件的 SetFloat() 函数设置定义的浮点类型 Speed 参数(第 25 行)。设置的速度值我们可以从 NavMeshAgent.velocity 中获取,通过 sqrMagnitude 把向量转为标量。

代码清单 1 传递速度值
  1. public class PlayerController : MonoBehaviour
  2. {
  3.     NavMeshAgent m_navMeshAgent;
  4.     Animator     m_animator;
  5.     void MoveToTarget(Vector3 destination)
  6.     {
  7.         m_navMeshAgent.destination = destination;
  8.     }
  9.  
  10.     void Awake()
  11.     {
  12.         m_navMeshAgent = GetComponent<NavMeshAgent>();
  13.         m_animator     = GetComponent<Animator>();
  14.     }
  15.  
  16.     // Start is called before the first frame update
  17.     void Start()
  18.     {
  19.         MouseManager.GetInstance().OnMouseClick += MoveToTarget;
  20.     }
  21.  
  22.     // Update is called once per frame
  23.     void Update()
  24.     {
  25.         m_animator.SetFloat("Speed", m_navMeshAgent.velocity.sqrMagnitude);
  26.     }
  27. }

最终的效果如图 7 所示,因为三档动画阈值范围不明显,所以导致看起来只有待机和奔跑两个动作。不过目前已经满足我们的需求了。如果想要实现行走状态,可以设置图 6 中的阈值状态,或更改传入速度值的逻辑进行实现。

图7 实现效果