一、状态机的概述

状态机由三部分构成

  • 状态:持有条件和状态的映射map。进入状态,持续状态和退出状态的实质方法。
  • 条件:持有一个判定判定条件,返回true或者false。
  • 机制:持有所有状态的实例,对状态进行执行。

二、示例代码

1、状态

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace net.realmoon
{
    public abstract class FSMState
    {
        public string stateID;
        /// <summary>
        /// key conditionID
        /// value StateID
        /// </summary>
        public Dictionary<string, string> conditionAndStateMap;
        public List<FSMCondition> fsmConditions;

        public FSMState()
        {
            conditionAndStateMap = new Dictionary<string, string>();
            fsmConditions = new List<FSMCondition>();
            Init();
        }

        /// <summary>
        /// ID赋值
        /// </summary>
        public abstract void Init();

        /// <summary>
        /// 增加一个条件状态转换
        /// </summary>
        /// <param name="conditionID"></param>
        /// <param name="stateID"></param>
        public void AddConditioAndState(string conditionID, string stateID)
        {
            conditionAndStateMap.Add(conditionID, stateID);
            CreateCondittion(conditionID);
        }

        /// <summary>
        /// 获取条件
        /// </summary>
        /// <param name="conditionID"></param>
        public FSMCondition GetCondition(string conditionID)
        {
            return fsmConditions.Find((obj) => obj.conditionID == conditionID);
        }

        /// <summary>
        /// 增加一个条件
        /// </summary>
        /// <param name="conditionID"></param>
        public void CreateCondittion(string conditionID)
        {
            Type conditionType = Type.GetType(conditionID + "Condition");
            FSMCondition condition = Activator.CreateInstance(conditionType) as FSMCondition;
            fsmConditions.Add(condition);
        }

        /// <summary>
        /// 检查是否条件切换
        /// </summary>
        /// <param name="fsmBase"></param>
        public void Reason(FSMBase fsmBase)
        {
            for (int i = 0; i < fsmConditions.Count; i++)
            {
                if (fsmConditions[i].CheckCondition(fsmBase))
                {
                    fsmBase.ChanegActiveState(conditionAndStateMap[fsmConditions[i].conditionID]);
                    return;
                }
            }
        }

        /// <summary>
        /// 进入条件
        /// </summary>
        public virtual void StateEnter(FSMBase fsm) { }
        /// <summary>
        /// 保持条件
        /// </summary>
        public virtual void StateStay(FSMBase fsm) { }
        /// <summary>
        /// 退出条件s
        /// </summary>
        public virtual void StateExit(FSMBase fsm) { }

    }

    public class FSMStateID
    {
        public const string Default = "";
    }
}

2、条件

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace net.realmoon
{
    public abstract class FSMCondition
    {
        public string conditionID;
        public FSMCondition()
        {
            Init();
        }

        /// <summary>
        /// ID赋值
        /// </summary>
        public abstract void Init();

        /// <summary>
        /// 检查条件
        /// </summary>
        /// <returns></returns>
        public abstract bool CheckCondition(FSMBase fsm);
    }
    public enum FSMConditionID
    {

    }
}

3、状态机

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace net.realmoon
{
    public class FSMBase : MonoBehaviour
    {
        [HideInInspector]
        /// <summary>
        /// 默认状态ID
        /// </summary>
        public string defaultFSMStateID;

        public List<FSMState> fsmStates;
        [HideInInspector]
        public FSMState currentFSMState;
        private FSMState defaultFSMState;

        public virtual void Start()
        {
            ConfigFSM();
            InitComponent();
            InitDefaultState();
        }

        /// <summary>
        /// 初始化状态机
        /// </summary>
        public virtual void ConfigFSM()
        {
            fsmStates = new List<FSMState>();
        }

        /// <summary>
        /// 初始化获取组件
        /// </summary>
        public virtual void InitComponent()
        {

        }

        // Update is called once per frame
        public virtual void Update()
        {
            if (currentFSMState == null)
            {
                return;
            }
            currentFSMState.Reason(this);
            currentFSMState.StateStay(this);
        }

        /// <summary>
        /// 设置初始状态
        /// </summary>
        private void InitDefaultState()
        {
            defaultFSMState = fsmStates.Find((obj) =>
            {
                return obj.stateID == defaultFSMStateID;
            });
            currentFSMState = defaultFSMState;
            if (currentFSMState == null)
            {
                return;
            }
            currentFSMState.StateEnter(this);
        }

        /// <summary>
        /// 切换状态机的状态
        /// </summary>
        /// <param name="stateID"></param>
        public void ChanegActiveState(string stateID)
        {
            currentFSMState.StateExit(this);
            if (stateID == FSMStateID.Default)
            {
                currentFSMState = defaultFSMState;
            }
            else
            {
                currentFSMState = fsmStates.Find((obj) => obj.stateID == stateID);
            }
            currentFSMState.StateEnter(this);
        }
    }
}
最后修改日期: 2023年10月19日

作者

留言

撰写回覆或留言

发布留言必须填写的电子邮件地址不会公开。