Unity/C# 有限狀態機

遊戲中角色控制有不少狀態,若是靠傳統的全局屬性而後經過swich和if來判斷的話,擴展性差,重複代碼多.git

經過編寫一個狀態管理庫來解決狀態變化的優勢有github

  • 代碼整潔
  • 可複用
  • 易管理

什麼是有限狀態機?

有限狀態機,(英語:Finite-state machine, FSM),又稱有限狀態自動機,簡稱狀態機,是表示有限個狀態以及在這些狀態之間的轉移和動做等行爲的數學模型。[1] bash

如圖所示: 主角從跑狀態切換到跳狀態,從跳狀態切換到二段跳狀態,這裏的切換就是指狀態的轉移。狀態的轉移是有條件的,好比主角從跑狀態不能夠直接切換到二段跳狀態。可是能夠從二段跳狀態切換到跑狀態。

另外,一個基本的狀態有:進入狀態、退出狀態、接收輸入、轉移狀態等動做。可是僅僅做爲跑酷的角色的狀態管理來講,只須要轉移狀態就足夠了。有興趣的同窗能夠自行擴展。函數

上代碼

代碼註釋不少,因此直接看代碼配合註釋理解的更快ui

/*
 * 
 *      Title:
 *          狀態機/狀態管理庫
 *         
 *      Description:
 *          多種狀態切換,比傳統的 全局參數+if/switch來切換狀態 更整潔和易擴展
 *          1.簡易狀態控制:經過添加狀態名稱,回調方法. 調用改變狀態方法來回調函數和參數.
 *          2.狀態機控制,經過添加幾種轉換的模式,再經過轉換行爲來找到轉換後的狀態並執行方法.
 *      Date:
 *          2018年1月18日 12:48:13
 *        
 *      Modify Recoder:
 *          1.0
 *        
 */
namespace XYFramework
{

    using System.Collections.Generic;

    public class XYState
    {
        #region 參數
        /// <summary>
        /// 回調函數
        /// </summary>
        /// <param name="param"></param>
        public delegate void XYCallbackFunc(params object[] param);
        /// <summary>
        /// 狀態名稱
        /// </summary>
        public string State { get; private set; }

        /// <summary>
        /// 存儲狀態回調參數的字典
        /// </summary>
        private readonly Dictionary<string, XYSimpleStateModel> _simpleStateDict = new Dictionary<string, XYSimpleStateModel>();

        /// <summary>
        /// 存儲狀態機轉換StateModel用字典
        /// </summary>
        private readonly Dictionary<string, XYTranslationStateModel> _translateStateDict = new Dictionary<string, XYTranslationStateModel>();

        #endregion


        #region Model
        /// <summary>
        /// 記錄狀態名稱,和轉換XYTranslation對象
        /// </summary>
        class XYTranslationStateModel
        {
            private string _name;

            public XYTranslationStateModel(string name)
            {
                _name = name;
            }

            /// <summary>
            /// 記錄狀態名和轉換狀態對象的字典
            /// </summary>
            public readonly Dictionary<string, XYTranslateModel> TranslationDict = new Dictionary<string, XYTranslateModel>();
        }

        /// <summary>
        /// 簡易回調數據模型
        /// </summary>
        public class XYSimpleStateModel
        {
            public string State;
            public XYCallbackFunc CallbackFunc;
            public XYSimpleStateModel(string state, XYCallbackFunc callBackFunc)
            {
                State = state;
                CallbackFunc = callBackFunc;
            }
        }

        /// <summary>
        /// 狀態轉換數據模型
        /// </summary>
        public class XYTranslateModel
        {
            public string FromState;
            public string Name;
            public string ToState;
            public XYCallbackFunc OnTranslationCallback;// 回調函數

            public XYTranslateModel(string fromState,string name,string toState,XYCallbackFunc onTranslationCallback)
            {
                FromState = fromState;
                Name = name;
                ToState = toState;
                OnTranslationCallback = onTranslationCallback;
            }
        }


        #endregion


        #region 狀態控制方法
        /// <summary>
        /// 添加一個新狀態
        /// </summary>
        /// <param name="name">狀態名稱</param>
        public void AddState(string name)
        {
            _translateStateDict[name] = new XYTranslationStateModel(name);
        }

        /// <summary>
        /// 設定最開始的狀態
        /// </summary>
        /// <param name="name"></param>
        public void StartState(string name)
        {
            State = name;
        }

        /// <summary>
        /// 添加一種狀態,和回調方法
        /// </summary>
        /// <param name="state">狀態名稱</param>
        /// <param name="callbackFunc">回調方法</param>
        /// <param name="param">回調參數</param>
        public void AddSimpleState(string state, XYCallbackFunc callbackFunc)
        {
            _simpleStateDict[state] = new XYSimpleStateModel(state, callbackFunc);
        }

        /// <summary>
        /// 添加一種轉換狀態監聽
        /// </summary>
        /// <param name="fromState">原來是那種狀態</param>
        /// <param name="name">轉換行爲名稱</param>
        /// <param name="toState">轉換爲那種狀態</param>
        /// <param name="callbackFunc">回調方法</param>
        public void AddTranslateState(string fromState,string name,string toState, XYCallbackFunc callbackFunc)
        {
            _translateStateDict[fromState].TranslationDict[name] = new XYTranslateModel(fromState, name, toState, callbackFunc);
        }


        /// <summary>
        /// 改變狀態
        /// </summary>
        /// <param name="state">狀態名</param>
        /// <param name="param">參數</param>
        public void ChangeState(string state,params object[] param)
        {
            if (_simpleStateDict.ContainsKey(state) == false)
            {
                XYLog.LogError("未找到這個狀態");
                return;
            }
            XYSimpleStateModel simple = _simpleStateDict[state];
            simple.CallbackFunc(param);
            State = state;
        }

        /// <summary>
        /// 經過傳入事件名,自動轉換狀態
        /// </summary>
        /// <param name="name">轉換事件名稱</param>
        /// <param name="param">參數</param>
        public void TranslateState(string name,params object[] param)
        {

            if (State != null)
            {
                XYLog.LogError("未賦值初始狀態");
                return;
            }
            if (_translateStateDict[State].TranslationDict.ContainsKey(name))
            {
                XYLog.LogError("未找到這個轉換狀態");
                return;
            }
            XYTranslateModel tempTranslation = _translateStateDict[State].TranslationDict[name];
            tempTranslation.OnTranslationCallback(param);
            State = tempTranslation.ToState;
           
        }
        #endregion

        /// <summary>
        /// 清理這個實例的存儲
        /// </summary>
        public void Clear()
        {
            _translateStateDict.Clear();
        }

    }//class_end

}

複製代碼

效果

中間還搭配使用了一個Log庫,感興趣的能夠一塊兒看一下spa

倉庫地址:https://github.com/Lafree317/XYFrameWork3d

相關文章
相關標籤/搜索