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效果则会用到神经网络算法。如有错误,欢迎指正!

 

posted @ 2018-12-29 18:32  微束网络  阅读(560)  评论(0编辑  收藏  举报