加强对有限状态机的理解

有限状态机核心类包括FSMState和FSMSystem这两个类:
1.FSMState类主要作为各种状态的基类而存在,内部核心字典主要包括两部分,其中KEY值一般保存转换条件,Value值保存状态ID,这两部分通过枚举的方式进行写入.作为基类基本方法包括:
(1) 添加键值的方法
(2) 移除键值的方法
(3) 根据键获取值的方法
(4) 状态开始之前的处理方法
(5) 状态结束之前的处理方法
(6) 状态运行中的处理方法
2.FSMSystem就是一个管理类,有限状态机的核心思想就是把各种状态从简单的switch case语句中抽离出来,具体到一个个类中,每一状态类都包含一个字典,字典中又包含转换条件,状态/ID这两个键值对,作为基类基本方法包括:
(1) 添加键值的方法
(2) 移除键值的方法
(3) 初始状态启动的方法
(4) 获取当前状态的方法(第一次获取应该从初始启动方法中给予赋值,在转换状态的方法中给及刷新)
(5) 转换状态的方法

有限状态机可以理解为针对一个状态的复杂的对象,通过两个类来替代switch方法,

例如: 卫兵A有两种状态 巡逻/追击 巡逻到追击状态的切换条件是发现敌人,追击到巡逻状态的切换条件是敌人死亡,切换条件跟状态以枚举的方式保存在两个枚举当中.对于卫兵各种状态的控制通过Guard这个类来实现,所以这个类中肯定要有一个成员变量FSMSystem,通过FSMSystem fsmSystem= new FSMSystem()来实例化一个状态管理类,把初始状态通过通过添加方法添加到字典中,同时巡逻跟追击两个类也要实例化出来,其字典中保存的是面对条件要转变到哪个类.

public class Guard : MonoBehaviour
{
    private FSMSystem fsmSystem;
    private PatrolState patrolState;
    private AttackState attackState;

    private void Start()
    {
        patrolState = new patrolState();
        attackState=new attackState();
        fsmSystem=new FSMSystem();
        patrolState.AddTranstion(Transitons.find, StateId.attack);
        attackState.AddTranstion(Transitons.died, StateId.patrol);
        fsmSystem.AddState(patrolState);
        fsmSystem.AddState(attackState);
        fsmSystem.InitState(patrolState);
        fsmSystem.TransitonState(Transitons.died);
    }
}

FSMSystem 核心代码

public class FSMSystem
{
    //状态容器
    private Dictionary<StateId, FSMState> statesDic;
    //当前状态
    private FSMState currentState;

    public FSMSystem()
    {
        statesDic = new Dictionary<StateId, FSMState>();
    }

    /// <summary>
    /// 添加
    /// </summary>
    /// <param name="trans"></param>
    /// <param name="state"></param>
    public void AddState(FSMState fsmstate)
    {
        if (fsmstate.ID == StateId.nullStateId)
        {
            Debug.Log("状态为空,添加失败");
            return;
        }

        if (statesDic.ContainsKey(fsmstate.ID))
        {
            Debug.Log("状态已存在,不能重复添加");
            return;
        }
        statesDic.Add(fsmstate.ID, fsmstate);
    }

    /// <summary>
    /// 删除
    /// </summary>
    /// <param name="trans"></param>
    public void DelState(FSMState fsmstate)
    {
        if (fsmstate.ID == StateId.nullStateId)
        {
            Debug.Log("状态为空,删除失败");
            return;
        }

        if (!statesDic.ContainsKey(fsmstate.ID))
        {
            Debug.Log("状态不存在,删除失败");
            return;
        }
        statesDic.Remove(fsmstate.ID);
    }

    /// <summary>
    /// 获取当前状态
    /// </summary>
    /// <param name="trans"></param>
    /// <returns></returns>
    public FSMState GetCurrentState(StateId id)
    {
        if (id == StateId.nullStateId)
        {
            Debug.Log("状态为空,返回空");
            return null;
        }

        if (!statesDic.ContainsKey(id))
        {
            Debug.Log("状态不存在,返回空");
            return null;
        }
        return statesDic[id];
    }

    /// <summary>
    ///  启动初始状态
    /// </summary>
    public void InitState(FSMState initState)
    { 
        currentState = initState;
        initState.OnBeforeEnter();
        initState.OnInState();    
    }

    /// <summary>
    /// 状态转换
    /// </summary>
    /// <param name="fsmState"></param>
    public void TransitonState(Transitons trans)
    {
        if (trans == Transitons.nullTransiton)
        {
            Debug.Log("转换条件为空值,状态转换失败");
            return;
        }
        if (!currentState.RelDic.ContainsKey(trans))
        {
            Debug.Log("当前状态不包含对应的转换条件,状态转换失败");
        }
        //当前状态结束前执行的方法
        currentState.OnBeforeEnd();
        currentState = statesDic[currentState.GetStateId(trans)];
        //新状态开始前执行的方法
        currentState.OnBeforeEnter();
        //新状态运行中
        currentState.OnInState();
    }
}

FSMState 核心代码


public enum Transitons
{
    nullTransiton=0,
    find,
    died
}

public enum StateId
{
    nullStateId=0,
    attack,
    patrol
}

public abstract class FSMState
{
    //容器
    public Dictionary<Transitons, StateId> RelDic;
    //状态对应的id
    protected StateId id;

    public StateId ID
    {
        get { return id; }
    }

    /// <summary>
    /// 添加
    /// </summary>
    /// <param name="trans"></param>
    /// <param name="state"></param>
    public void AddTranstion(Transitons trans, StateId state)
    {
        if (trans == Transitons.nullTransiton)
        {
            Debug.Log("状态条件为空,添加失败");
            return;
        }

        if (RelDic.ContainsKey(trans))
        {
            Debug.Log("状态条件已存在,不能重复添加");
            return;
        }
        RelDic.Add(trans, state);
    }

    /// <summary>
    /// 删除
    /// </summary>
    /// <param name="trans"></param>
    public void DelTranstion(Transitons trans)
    {
        if (trans == Transitons.nullTransiton)
        {
            Debug.Log("状态条件为空,删除失败");
            return;
        }

        if (!RelDic.ContainsKey(trans))
        {
            Debug.Log("状态条件不存在,删除失败");
            return;
        }
        RelDic.Remove(trans);
    }

    /// <summary>
    /// 获取值
    /// </summary>
    /// <param name="trans"></param>
    /// <returns></returns>
    public StateId GetStateId(Transitons trans)
    {
        if (trans == Transitons.nullTransiton)
        {
            Debug.Log("状态条件为空,返回空");
            return StateId.nullStateId;
        }

        if (!RelDic.ContainsKey(trans))
        {
            Debug.Log("状态条件不存在,返回空");
            return StateId.nullStateId;
        }
        return RelDic[trans];
    }

    /// <summary>
    /// 进入状态之前
    /// </summary>
    public abstract void OnBeforeEnter();

    /// <summary>
    /// 结束状态之前
    /// </summary>
    public abstract void OnBeforeEnd();

    /// <summary>
    /// 状态运行中
    /// </summary>
    public abstract void OnInState();
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值