Unity/Animator -- 创建Animator Controller

前言

在Unity里,我们可以自己制作动画效果, 亦或是使用别人制作好的动画素材,为模型和UI赋予活力。然而,通常情况下,一个单独的动画(即Animation Clip)可能无法很好地达到我们期望的效果,所以这时Animator Controller就能发挥其用武之地,帮助我们在合适的时间触发合适的动画,而不是在一个动画效果上无限循环。看完本篇文章,你应该就可以自己动手做一个具有静止,跳跃,奔跑等多个动作的角色,并可以在满足条件时触发相应的效果。

如果你对如何制作一个简单的动画(Animation Clip)还不是很熟悉,可以先去复习一下我之前写的Animation系列博文。

  • Unity/Animation – 创建Animation Clip
  • Unity/Animation – 调节Animation Curves
  • Unity/Animation – 添加动画事件(Animation Events)

Animator Controller工作原理

Animator Controller, 个人翻译为动画控制器,负责在不同的动画间切换,属于制作动画效果的必备原件。如果看过 Unity/Animation – 创建Animation Clip,你可能还记得在我们为一个GameObject创建动画时,Unity会自动帮我们生成一个Animation Clip和一个Animator Controller。因为我们之前只用到了一个动画效果,所以Animator Controller就没有进入我们的视线。在这里,我们有必要再次强调一下Animator Controller是如何生效的。

1. Animator组件

在Unity中,一个最基本的原则就是 想要GameObject实现某种功能,就要在它上面附加相应的组件。所以为了让一个GameObject拥有动画效果,相应的动画组件是必不可少的,在Unity,这个组件已经被定义好了,叫做 Animator。所以当你通过Animation窗口(还记得吗?快捷键是 Ctrl+6)中的 Create New Clip 创建Animation时,一个 Animator 已经悄无声息地出现在了对应的GameObject上。

Unity/Animator -- 创建Animator Controller_第1张图片

2. Animator Controller文件

在第一步中生成的Animator组件上, 有很多个让你头疼的参数,但不用担心,大部分情况下,你只会用到第一个,即 Controller 参数。不出意外的话,以上述方法创建的Animator已经被赋值了,你可以点击该值,并切换到Project窗口下,便会发现这个 Controller 对应的文件是一个 .controller 文件。它就是本篇文章的主角,Animator Controller的真面目。

Unity/Animator -- 创建Animator Controller_第2张图片

值得注意的是,你也可以通过GameObject上的 Add Component 添加一个崭新的 Animator 组件,但是这种情况下 AnimatorController 参数默认为空,所以需要我们手动将事先准备好的 .controller 文件拖拽到该参数位置,动画控制器才能正常工作。

3. Animation Clip文件

点击上一步中找到的Controller文件,我们可以在Inspector窗口中看到——好吧,啥也没有。。。不过没有关系,Unity专门准备了一个窗口方便我们管理这类文件,点击Inspector中的 Open 按钮(你也可以直接双击”.controller”文件,效果相同)。正常情况下会弹出一个 Animator 窗口,该窗口中显示的就是动画控制器文件中的所有内容(即使你的Animator窗口没有自动弹出,你也可以在顶部的工具栏通过 Window-Animator 打开这个界面)。

Unity/Animator -- 创建Animator Controller_第3张图片

是不是感觉有点复杂?没关系,我们一会再慢慢分析它的结构,现在主要看窗口右侧的大面积区域,你会看到四个颜色不同的矩形区块,它们分别是 Any State, Entry, Exit(该区块藏得比较深,你可以通过 Alt+鼠标左键拖动区域找到它 ) 以及 New Animation(这个区块的名字根据你创建Animation时指定的文件名而定)。前三个都是Animator Controller文件创建时自带的,之后在用到它们时我们再具体讲解,最后一个则是我们“创建”的。通过点击 New Aniamtion,你同样可以在Inspector窗口中看到该区块对应的参数。

Unity/Animator -- 创建Animator Controller_第4张图片

我们暂时只关注第一个参数,即 Motion,点击参数对应的值同样可以在Project窗口中找到高亮显示的对应文件。如果你记性不错的话,应该就会明白,这个New Animation区块中指定的参数,就是我们之前手动创建的 Animation Clip 文件。

4. 总结

到这里,我们就可以缕清一个动画系统(Unity中被称为Mecanim)生效的流程了。首先,GameObject通过绑定 Animator 组件来获得使用动画的能力;之后,我们可以为 Animator 组件指定 Controller 参数,即定义好的 Animator Controller 文件决定GameObject使用的动画效果;最后,每个 Animation Clip 都被盛放在 Animator Controller 中的一个区块(或理解为容器)中,从而方便在一个控制器中管理多个动画短片。我们学习 Animator Controller,无非是学习 如何管理每个动画短片,并且让GameObject在满足某种条件时进行跳转到相应的动画

Animator窗口介绍

相信对动画系统生效的过程有了一个大致的了解之后,你一定迫切地想知道之前我们匆匆一瞥的Animator窗口究竟有哪些神奇的功能。那么接下来的一个小节我们就会对那些用得到的部分进行详细的介绍。首先回到之前的Animator窗口,根据布局我们可以将其分为三个部分,如下图所示:

Unity/Animator -- 创建Animator Controller_第5张图片

区域1. Layers/Parameters面板

该区域实际上由两个标签页构成,它们分别是 LayersParameters 。Layers标签页中的内容在小型项目中我们基本用不到,没有具体的人物模型也不好学习,暂时你可以忽略它。而另外一个Parameters标签页中的内容可以说是Animator必需的,包含了我们在Animator中使用的所有“参数”。在拥有多个动画短片的控制器中,正是通过Parameters中的参数实现了不同动画间的转变。

Unity/Animator -- 创建Animator Controller_第6张图片

切换到Parameters标签页后,我们可以通过点击“+”创建4中类型的参数,它们分别是Float、Int、Bool和Trigger。前三个都比较好理解,均属于基本数据类型。最后一个Trigger则是一个与Bool类似的参数,同样拥有True和False两种状态。但是不像Bool在设置为True后会一直维持,Trigger在被触发后会迅速重置为未触发状态。这个特性在设置动画转变时非常实用。

区域2. Layer 层次导航栏

该区域显示了当前状态机所在的Layer层次结构,默认情况下为Base Layer。至于右侧的Auto Live Link,保持默认值即可,官方文档也没有给出它的明确用途。

区域3. 当前Layer状态机

该区域才是Animator中最重要的部分,之前我们称呼它们为“颜色各异的矩形区块”,实际上它们正式的名字为状态机(State Machine)。状态机包含了不同的状态(State)和状态间的过渡关系(Transition),如果你想了解关于状态机的详细内容,可以参考Unity官方手册中的 State Machine Basics, 本质无非是一个特殊的有向图。

状态机的状态(State)

每个Animator Controller都会自带三个状态:Any State, Entry 和 Exit。


  1. Any State,表示任意状态的特殊状态,以蓝色标识,例如我们如果希望角色在任何状态下都有可能切换到死亡状态,那么Any State就可以帮我们做到。当你发现 某个状态可以从任何状态以相同的条件跳转到 时,那么你就可以用Any State来简化过渡关系。
  2. Entry, 表示状态机的入口状态,以绿色标识。当我们为某个GameObject添加上Animator组件时,这个组件就会开始发挥它的作用。之前也说过一个Animator Controller用于控制多个Animation的播放,那么默认情况下Animator组件会播放哪个动画呢? ——这就是由Entry决定的。但是Entry本身并不包含动画,而是指向某个带有动画的状态,并设置其为默认状态。被设置为默认状态的状态会显示为 橘黄色。当然,你可以随时在任意一个状态上通过 鼠标右键->Set as Layer Default State 更改默认状态。记住, Entry 在Animator组件被激活后 无条件 跳转到默认状态,并且每个Layer 有且仅有一个 默认状态。
  3. Exit, 表示状态机的出口状态,以红色标识。如果你的动画控制器只有一层,那么这个状态可能并没有什么卵用。但是当你需要从子状态机中返回到上一层(Layer)时,把状态指向Exit就可以了。

关于子状态机(Sub-Machine)的问题,以后有空再说吧,有兴趣的也可以自己查阅Unity官方手册。
除了上述三个自带的状态,Animator Controller的主角还是我们人为添加的各种状态。你可以把这些自定义的状态看做一个 盛放动画的容器 ,它们可以表示一个准备好的动画效果,并且可以在这些Animation Clip上“添油加醋”,再做一些只适用于当前动画控制器的处理。创建一个自定义状态可以通过在区域3中的任何空白区域 鼠标右键->Create State->Empty来实现。我们可以选中某个自定义状态,并在Inspector窗口下观察它具有的属性:

Unity/Animator -- 创建Animator Controller_第7张图片

属性名 描述
Motion 状态对应的动画。每个状态的基本属性,直接选择已定义好的动画即可
Speed 动画播放的速度。还记得吗?之前创建Animation Clip的时候我们通过每秒播放的帧数(fps)控制动画速度,如果你希望在状态机中进行快慢的进一步调节,使用该选项即可。默认值为1,表示速度为原动画的1.0倍。
Mutiplier 勾选右侧的Parameter后可用,即在计算Speed的时考虑 区域1 中定义的某个参数。若选择的参数为smooth, 则动画播放速度的计算公式为 smooth * speed * fps(animation clip中指定)
Mirror 仅适用于humanoid animation(人型机动画),不在文章讨论范围内
Cycle Offset 周期偏移,取值范围为0-1.0,用于控制动画起始的偏移量。把它和正弦函数的offset进行对比就能够理解了,只会影响起始动画的播放位置。
Foot IK 仅适用于humanoid animation(人型机动画),不在文章讨论范围内
Write Default 并没有理解其真正作用,最好保持默认,感兴趣可以参考官方手册
Transitions 该状态向其他状态发起的过渡列表,包含了Solo和Mute两个参数,在预览状态机的效果时起作用,不在本文讨论范围内
Add Behaviour 用于向状态添加“行为”,属于高级用法,不在本文讨论范围内

状态间的过渡关系(Transitions)

除了包含特定动画的状态,状态机更少不了充当不同状态间纽带关系的Transitions,直观上说它们就是连接不同状态的 有向箭头

Unity/Animator -- 创建Animator Controller_第8张图片

以上图为例,我们已经创建了三个自定义状态Idle, Walk 和Run,并且Idle已经被设置为初始状态(以橙色表示)。所以Animator组件生效时会一直处于Idle状态,如果在Animation Clip的属性中勾选了 “Loop Time”,那么该动画会循环播放,否则播放一次GameObject就会停止。这种效果在GameObject是背景的大树,花草什么的就够用了,因为它们都不会动。但是我们的主角大部分情况下还是需要移动的,所以我们机智地也准备好了走路(Walk)和奔跑(Run)两种动画。不过Unity还没有智能到在物体移动的时候自动跳转到名为“Walk”的状态上,所以这个切换的时机还是需要我们控制的。记得我们之前说的Parameters面板嘛?它们就是在这里排上用场的。

让我先暂时假定一种方案:
1. 物体在玩家按下方向键时开始步行(Walk),并且速度会一直上升;
2. 物体在速度达到10.0时会播放奔跑(Run)动画;
3. 玩家松开方向键后回到静止(Idle)状态。

那么我们可以定义两个Parameter来模拟过渡条件:
1. isMove, bool类型, 用于判断用户是否按下按键;
2. moveSpeed, float类型, 用于判断GameObject的速度是否达到10.0。

状态间的过渡关系可能有五种:
1. Idle -> Walk, 条件为 isMove=true
2. Walk -> Idle, 条件为 isMove=false
3. Walk -> Run, 条件为 moveSpeed > 10.0
4. Run -> Walk, 条件为 moveSpeed < 10.0
4. Run->Idle, 条件为 isMove=false

要创建一个从状态A到状态B的过渡,直接在状态A上 鼠标右键单击 > Make Transition并把出现的箭头拖拽到状态B上点击鼠标左边即可。而设置对应于某个过渡关系的过渡条件,直接选中过渡线并在Inspector窗口中的Conditions属性一栏添加即可(添加的条件为&&关系,即必须同时满足)。

关于Conditions的设置有几点注意事项还是需要说明一下:首先必须在Parameters面板中添加了参数才可以在这里查看到,其次添加的条件为&&”与”关系,即必须同时满足。

Unity/Animator -- 创建Animator Controller_第9张图片

知道了上面这些,我们就可以轻松地完成动画状态机的编写了,正常情况下你的Animator视图应该如下图所示:

Unity/Animator -- 创建Animator Controller_第10张图片

还有更多…

经过上述步骤,你应该就可以获得一个可以正常工作的Animator了,我们已经知道状态间的过渡是通过参数来设置的,但是目前为止我们仍未改变过任何参数的的值,除了创建它们时Unity的默认值。下次更新会在Transition上着墨更多,为了不使本文显得过于冗长,这次就到这里吧。。。(绝对不是写太长了自己都晕了)

你可能感兴趣的:(unity开发)