前言
为了提高玩家的游戏体验,我们常常需要在角色运动的时候,根据它的运动状态播放对应的动画。为了能够控制当前播放什么动画,我们首先需要制作动画状态机,再用代码去控制动画状态机切换当前的状态,从而切换当前播放的动画。
制作角色的动画状态机
我们在给角色制作动画状态机来控制我们之前制作好的角色动画之前,我们需要确定我们有哪些状态
,以及控制这些状态转移的条件
是什么。
各个角色动画之间的状态转换规则如下:
- 当角色不
着地
时,不播放任何状态- 角色
着地
时播放Idle播放动画- 当角色
着地
且水平移动
时,播放Walk动画- 当角色触发
跳跃
事件时,播放Jump动画- Jump动画播放完之后,
着地
播放Idle动画- 当角色触发
射击
事件时,播放Shoot动画- Shoot动画播放完之后,
着地
播放Idle动画- 当角色触发
死亡
事件时,播放Death动画- Death动画播放完之后,自动播放Falling动画
根据状态转换规则,我们可以得出控制状态转换的所有参数
状态转换参数:
- Grounded:Bool
- Speed:Float
- Jump:Trigger
- Death:Trigger
- Shoot:Trigger
接着,我们在Unity顶部菜单栏选中Window->Animator
打开动画状态机编辑窗口,然后在Hierarchy
窗口中选中Player
编辑角色的动画状态机。在Unity中,一个状态控制一个动画。根据上面状态转换规则,我们还需要创建一个没有任何动画的空状态,并将其作为整个状态机的默认状态。我们在Animator
窗口中点击鼠标右键选择Empty
创建一个空状态,将其命名为Empty
之后,点击鼠标右键编辑这个状态,然后选择Set as Layer Default State
将其设置为默认状态。最后,我们根据上面得到的控制状态转换的所有参数来创建状态转换参数,并构建角色的动画状态机如下:
创建完动画状态机之后,我们为状态之间的转移边设置条件。点击状态之间的转移边,然后在右侧的Inspector面板进行设置。
每条转移边的具体设置如下:
- Empty -> Idle:
- Has Exit Time:
false
- Interruption Source":
Next State
- Conditions:
Grounded(true)
- Idle -> Empty:
- Has Exit Time:
false
- Conditions:
Grounded(false)
- Idle -> Walk:
- Has Exit Time:
false
- Conditions:
Speed(Greater 0.1)
- Walk -> Idle:
- Has Exit Time:
false
- Interruption Source":
Next State
- Conditions:
Speed(Less 0.1)
- Walk -> Empty:
- Has Exit Time:
false
- Conditions:
Grounded(false)
- AnyState -> Jump:
- Has Exit Time:
false
- Can Transition To Self:
false
- Conditions:
Jump(Trigger)
- Jump -> Empty:
- Has Exit Time:
true
- Interruption Source":
Next State
- Conditions: List is Empty
- AnyState -> Shoot:
- Has Exit Time:
false
- Can Transition To Self:
True
- Conditions:
Shoot(Trigger)
- Shoot -> Empty:
- Has Exit Time:
true
- Interruption Source":
Current State then Next State
- Conditions: List is Empty
- AnyState -> Death:
- Has Exit Time:
false
- Can Transition To Self:
false
- Conditions:
Death(Trigger)
- Death -> Falling:
- Has Exit Time:
true
- Conditions: List is Empty
加入控制代码
角色的动画状态机编辑完成之后,我们还需要使用代码来控制动画状态机的状态转移。打开PlayerController.cs
,插入动画控制代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(Rigidbody2D))]
[RequireComponent(typeof(AudioSource))]
[RequireComponent(typeof(Animator)