评论

收藏

unity中实现FSM有限状态机

游戏开发 游戏开发 发布于:2021-07-18 09:00 | 阅读数:378 | 评论:0

有限状态机(FSM)在游戏中的运用非常广泛. 使用它编程快速简单, 并且易于理解.
#FSM由以下几个部分组成
      
  • 内在的所有状态  
  • 输入条件  
  • 状态之间起到连接性作用的转换函数
#在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);
很方便,有没有..

关注下面的标签,发现更多相似文章