unity中实现FSM有限状态机

不打扰是莪最后的温柔 提交于 2020-03-01 11:08:12

有限状态机(FSM)在游戏中的运用非常广泛. 使用它编程快速简单, 并且易于理解.

#FSM由以下几个部分组成

  1. 内在的所有状态
  2. 输入条件
  3. 状态之间起到连接性作用的转换函数

#在Unity中使用FSM 通常实现一个FSM我们的写法一般是这样的. ##定义枚举定义的状态

public enum Hero_Enum {
    Wait,
    Move,
    Attack,
    Die
}

这里我们定义一个主角, 它有4个状态分别是等待,移动,攻击,死亡四个状态.

声明一个局部变量表明当前所处的状态

private Hero_Enum currState;

定义状态转换函数

public void SetState (Hero_Enum newState) {
    currState = newState;
    switch (currState) {
        case Hero_Enum.Wait:
              WaitEnter();
              break;
        case Hero_Enum.Move:
             MoveEnter();
             break;
        case Hero_Enum.Attack:
            AttackEnter();
            break;
       case Hero_Enum.Die:
            DieEnter();
            break;
    }
}

定义更新函数

在不同的状态下我们需要执行相对应的逻辑, 那写法如下:

public void Update() {
    switch (currState) {
        case Hero_Enum.Wait:
            DoWait();
            break;
        case Hero_Enum.Move:
            DoMove();
            break;
        case Hero_Enum.Attack:
            DoAttack();
            break;
        case Hero_Enum.Die:
            DoDie();
            break;
    }
}

这里只是罗列了一下一个基本的FSM结构, 这样写下来发现敲得代码也不少, 那么问题来了, 有没有一个更好的办法来实现FSM呢?

答案是有, 在这里推荐一个比较好用的FSM框架, 它的原地址在 https://github.com/thefuntastic/Unity3d-Finite-State-Machine

thefuntastic/Unity3d-Finite-State-Machine使用方法

引入packet包

using MonsterLove.StateMachine; //Remember the using statement before the class declaration

public class MyManagedComponent : MonoBehaviour
{

}

定义FSM状态的Enum

public enum States
{
    Init, 
    Play, 
    Win, 
    Lose
}

创建状态机的引用变量

StateMachine<States> fsm;

初始化StateMachine

void Awake() {
    fsm = StateMachine<States>.Initialize(this);
}

这样一个状态机就已经创建好了, 定义好StateMachine以后, 它会自动为我们创建相应的回调函数. 使用方法是定义一个 状态名_方法名. 已经支持的方法有:

  • Enter
  • Exit
  • FixedUpdate
  • Update
  • LateUpdate
  • Finally

例如:

void Init_Enter()
{
    Debug.Log("We are now ready");
}
//Coroutines are supported, simply return IEnumerator
IEnumerator Play_Enter()
{
    Debug.Log("Game Starting in 3");
    yield return new WaitForSeconds(1);

    Debug.Log("Game Starting in 2");
    yield return new WaitForSeconds(1);

    Debug.Log("Game Starting in 1");
    yield return new WaitForSeconds(1);

    Debug.Log("Start"); 
}

void Play_Update()
{
    Debug.Log("Game Playing");
}

void Play_Exit()
{
    Debug.Log("Game Over");
}

当进入到Init状态到, 会自动执行我们刚刚定义的Init_Enter方法, 同时支持IEnumerator, 如上面的Play_Enter方法.

那么我们如何切换状态呢. 使用它就可以:

fsm.ChangeState(States.Init);

很方便,有没有..

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!