返回

状态者模式

状态者模式简介

NPC或者Boss有多个状态,比如巡逻、攻击、逃跑、狂暴等。状态者模式就是创建一个架构去管理这些状态的跳转。

简单代码例子

  • 状态跳转基类
public abstract class FSMState
{
    private byte stateId;
    //进入这个状态之前要处理的一些事情
    public virtual void OnBeforEntor()
    {
    }
    //从上一个状态复制一些东西
    public virtual void CopyState(byte curStateId)
    {
    }
    //每一个状态必须重写
    public abstract void OnEnter();
    //状态进行
    public virtual void Update()
    {
    }
    //离开这个状态需要处理的一些事情
    public virtual void OnLeave()
    {
    }
}
  • 状态的添加与管理
public class FSMManager
{
    private FSMState[] fsmManager;
    //增加了几个state
    private byte curAdd;
    public byte curStateId;
    public FSMManager(byte stateNumber)
    {
        curAdd = 0;
        curStateId = 0;
        fsmManager = new FSMState[stateNumber];
    }
    public void AddState(FSMState tmpState)
    {
        if (curAdd < fsmManager.Length)
        {
            fsmManager[curAdd] = tmpState;
            curAdd++;
        }
    }
    public void ChangeState(byte stateId)
    {
        fsmManager[curStateId].OnLeave();
        fsmManager[stateId].CopyState(curStateId);
        fsmManager[stateId].OnBeforEntor();
        fsmManager[stateId].OnEnter();
        curStateId = stateId;
    }
    public void Update()
    {
        fsmManager[curStateId].Update();
    }
}
  • 具体状态类
public class AtackFSM : FSMState
{
    public override void OnEnter()
    {
        throw new System.NotImplementedException();
    }
}
public class WalkFSM : FSMState
{
    public override void OnEnter()
    {
        throw new System.NotImplementedException();
    }
}
  • 调用状态的跳转
public class FSM : MonoBehaviour
{
    public enum FSMStateId
    {
        Idle,
        Attack,
        walk,
        MaxValue
    }
    FSMState stateId;
    FSMManager manager;

    void Start()
    {
        //WalkFSM tmpWalk = new WalkFSM();
        //AtackFSM tmpAttack = new AtackFSM();
        manager = new FSMManager((byte)FSMStateId.MaxValue);
        //manager.AddState(tmpWalk);
        //manager.AddState(tmpAttack);
    }

    public void PlayAttack()
    {
        manager.ChangeState((byte)FSMStateId.Attack);
    }
    void Update()
    {
        manager.Update();
    }
}
Licensed under CC BY-NC-SA 4.0
0