【Unity2DMobileGame_PirateBomb12】—— 动画状态机增加巡逻模式下切换动画

331 阅读2分钟

文章目录


制作敌人的动画优先考虑动画机可以应用在所有敌人的身上。

1. Animator窗口设置

1.1 从idle切换到run

从idle状态到run状态,敌人需要先在原地执行一次idle的动画,执行结束后,就执行run移动的动画,走到每一个目标点的时候切换到idle状态短暂停留,然后再进行移动。
所以代表着cucumber的动画除了run动画需要循环播放以外,其他都是单次执行的。

  • 逐一取消除run以外动画的loop
  • idle创建Transition
  • 条件是需要播放完整个动画,将ExitTime的百分比为修改为1
  • 取消勾选FixedDuration,并且将其设置为0

这样的话idle动画播放完以后会马上切换到run动画

1.2 从run切换回idle

当enemy移动到对应位置的时候,就把动画切换回idle,即每当移动到左右A,B两个目标点的时候,就把动画从run改回到idle状态。

  • run创建Transition
  • 创建一个整型的变量state对应各种状态,默认的初始值设置0,移动过程中再次回到idle的状态设置为state-Equals-0
  • 不需要退出时间和持续时间,取消勾选HasExitTime和FixedDuration并设置为0

2.代码实现动画效果

需要在Enemy实现的动画状态,添加控制动画状态机的变量,并初始化组件,初始化组件在独立的虚方法Init()方法中,并在Awake中调用。

public Animator anim;
// 初始化 方便子类进行修改
public virtual void Init()
{
    anim = GetComponent<Animator>();
}

// 确保游戏一开始变量有值,优先State执行
private void Awake()
{
    Init();
}

创建动画的参数来调用Animator中的Parameter

public int animState;

修改巡逻状态中的代码逻辑,

using UnityEngine;

public class PatrolState : EnemyBaseState
{
    public override void EnterState(Enemy enemy)
    {
        // 一进入游戏数值为0,表示从idle动画状态开始
        enemy.animState = 0;
        // 一进入状态找到巡逻的目标点
        enemy.SwitchPoint();
    }

    public override void OnUpdate(Enemy enemy)
    {
        // !如果正在播放的动画 (动画的层级).IsName("状态的名称")
        if (!enemy.anim.GetCurrentAnimatorStateInfo(0).IsName("idle"))
        {
            enemy.animState = 1;
            enemy.MoveToTarget();
        }

        // 每一帧把不断的循环 无限趋近于目标点 当前敌人的坐标以及当前敌人的目标点
        if (Mathf.Abs(enemy.transform.position.x - enemy.targetPonit.position.x) < 0.01f)
        {
            // 切换点以外,也同时切换回idle的状态
            // (这里的逻辑是,一切换到巡逻的状态先运行进入状态EnterState方法,进入anim初始化为0,再次执行idle的动画状态)
            enemy.TransitionToState(enemy.patrolState);
        }

        // 如果攻击列表内有物体,敌人就进行攻击 (巡逻模式切换到攻击状态)
        if (enemy.attackList.Count > 0)
            enemy.TransitionToState(enemy.attackState);
    }
}

在这里插入图片描述