打开Animator,右击打开选项,创建一个Blend Tree
创建好后是这样:
双击上图黄色的Blend Tree,会打开这样一个界面:
然后我们可以把这个Blend Tree改个名称(因为是初始状态,所以改为idle),并给它设置几个参数(Parameters):
接下来,点击Blend Tree回到之前的那个界面,选中它,并设置一下:
这样它会出现两个参数的滑块,然后我们把参数都重命名一下:
然后给这个Blend Tree添加4个运动场(Motion Field):
接着把我们创建好的属于idle状态的clips都分别赋给这四个运动场:
接着我们调整一下PosX和PosY中的数值:
这样做的意义是,当我们的参数inputX和inputY发生变化时,就能在Motion Field中检索到与输入数值对应的Motion状态,从而选择合适的Clip动画片段:
通过这个Blend Tree的功能我们可以发现,使用它来实现动画切换效果会多么方便!(特别是像该项目中动画状态的数量如此之多时)
接下来让我们把walk和run的混合树也都创建好,并给它们创建过渡(Make Transition):
接下来我们需要给不同动画状态间的过渡和切换设置一些触发条件:
比如当isWaking参数为true时,表示切换到walk动画状态
(通常我们不希望两个动画间的切换有明显的过渡延迟,所以会取消勾选Has Exit Time)
当我们创建好动画器相关的设置后,就需要开始编写脚本来控制它们了:
打开我们的脚本,首先需要声明一个Animator类型的变量(习惯用小驼峰命名法):
然后需要在Start()函数里将这个变量初始化:
(第二种初始化方法是:将变量声明为public类型,然后直接在Inspector面板中拖拽组件来完成初始化)
然后,我们需要定义一个函数用来实现动画切换的算法:
然后一定不要忘记此时我们只是定义了一个函数,还需要在Update()函数里调用它:
接下来让我们把其他状态的切换条件也都设置好吧:
private void PlayerAnim()
{
if(moveDirection != Vector2.zero)
anim.SetBool("isWalking", true);
else
anim.SetBool("isWalking", false);
anim.SetFloat("inputX", moveX);
anim.SetFloat("inputY", moveY);
if ((moveX != 0 || moveY != 0) && Input.GetKey(KeyCode.LeftShift)) //按住Shift和方向键会触发冲刺
anim.SetBool("isRunning", true);
else
anim.SetBool("isRunning", false);
}
效果如下:
更好的优化
在上面的PlayerAnim()代码中,我们用moveX和moveY来记录用户的方向输入,但造成的问题是——当用户停止输入时,moveX和moveY就会赋为0(因为moveX和moveY是用Input.GetAixs()来赋值的,当输入为空时就会被赋0),这样就会造成在Blend Tree中,参数inputX和inputY都变为0,混合树就会选择默认的Motion Field的动画片段(也就是我们默认设置的第一个片段),那样的话当角色朝着不同方向移动过程中,玩家突然停止方向键的输入,角色就会默认回到第一个片段(比如当玩家向左移动时突然停下来,角色朝向会突然变成Down而不是Left,这不是我们希望看到的):
(当参数为0时会默认选择第一个Clip)
解决方法就是,在用户输入方向键时,用另外的变量来记录下此刻玩家输入的值,然后当玩家停止输入时,一定要让单独设置的这些变量不要记录此时的输入值(因为是0),但要记录下上一刻的输入值(也就是停止输入前的最后一刻的输入值):
这样修改后,角色在移动时突然停止导致站立时也能朝向正确的方位了。