FSM有限状态机
1、什么是有限状态机
有限状态机(Finite State Machine),简称FSM,它由一组有限个状态、输入和根据输入及现有状态转换为下一个状态的转换函数组成,当然,通常每个状态机都必须有一个初始状态。它有两个重要的概念:状态和转移。有限状态机在很多领域都有运用,这里介绍的是在unity游戏开发中的运用。在游戏开发中,通常使用FSM去实现一些简单的AI逻辑,对于游戏中的每个对象,都可以在其生命周期中分出一些状态,比如一个小兵,它可能在休息,或者是在巡逻,当有敌人出现时,它的状态会变成追逐或者攻击敌人。当某些条件成立时,状态机从当前状态转移到下一个状态,在不同的状态下,游戏对象执行不同的任务。有限状态机中必须注意的是:必须要有一个初始状态,并保存当前状态,以及注意每个状态转移的必要条件。下面动手写一个简易的unity有限状态机。
2、定义有限状态机基类
public class FSMStateBase { //进入该状态时调用 public virtual void Enter() { } //每帧调用 public virtual void Update() { } //退出该状态时调用 public virtual void Exit() { } }
3、定义一组具体状态
public class IdleState : FSMStateBase { public override void Enter() { } public override void Update() { } public override void Exit() { } } public class WalkState : FSMStateBase { public override void Enter() { } public override void Update() { } public override void Exit() { } } public class AttackState : FSMStateBase { public override void Enter() { } public override void Update() { } public override void Exit() { } }
4、有限状态机使用示例
public class FSMManager : MonoBehaviour { public enum State { Walk, Idle, Attack } private State curState;//当前状态 private Dictionary<State, FSMStateBase> fsmDict = new Dictionary<State, FSMStateBase>(); private void Start() { curState = State.Idle; InitState(); } //添加一组状态 public void InitState() { fsmDict.Add(State.Walk, new WalkState()); fsmDict.Add(State.Idle, new IdleState()); fsmDict.Add(State.Attack, new AttackState()); } //转移状态 public void ChangeState(State state) { fsmDict[curState].Exit(); curState = state; fsmDict[curState].Enter(); } private void Update() { //模拟转换条件 if (Input.GetKeyDown(KeyCode.A)) { ChangeState(State.Walk); } else if (Input.GetKeyDown(KeyCode.B)) { ChangeState(State.Attack); } fsmDict[curState].Update(); } }
5、最后
上面完成了一个简单的FSM有限状态机使用示例,可以看到,状态转移条件判断会有很多if else语句,状态一多,就很容易出bug。可以看出,有限状态机在某条件下,它的转移状态是一i定的,有限状态机有一个变种,叫模糊状态机,在确定的条件下,它的转移状态不是百分百确定的,它有一定的概率会转移到另一个状态。还有其他状态机比如分层状态机,水平有限,这里就不做介绍了。一般有限状态机在unity中只用来做简易的AI,如果要实现复杂的状态逻辑,有限状态机明显会显得力不从心,因此稍微复杂一些的情况我们会使用行为树,一些高级的AI效果则会用到神经网络算法。如有错误,欢迎指正!