亚洲 国产精品 日韩-亚洲 激情-亚洲 欧美 91-亚洲 欧美 成人日韩-青青青草视频在线观看-青青青草影院

千鋒教育-做有情懷、有良心、有品質的職業教育機構

手機站
千鋒教育

千鋒學習站 | 隨時隨地免費學

千鋒教育

掃一掃進入千鋒手機站

領取全套視頻
千鋒教育

關注千鋒學習站小程序
隨時隨地免費學習課程

當前位置:首頁  >  技術干貨  > unity狀態機

unity狀態機

來源:千鋒教育
發布人:wjy
時間: 2022-07-29 17:01:00 1659085260

前言

眾所周知,Unity在開發游戲的時候經常用到狀態機,而通常情況下,我們會使用簡單的枚舉類型設置狀態,然后通過調整枚舉,來切換狀態,在簡單情況下是可以的,就像是Unity中Animator切換動畫狀態就是,直接通過動畫片段的名稱切換。而當狀態很多的時候,直接切換就顯得有些很不安全,而且友好性也不是很好,所以根據Unity中Animator這種通過條件切換狀態的架構,我寫了一個簡單的狀態機,給大家分享。

unity狀態機

外部委托定義

    /// <summary>

    /// 狀態內部事件委托

    /// </summary>

    public delegate void StateFunctionEventHandler();

    /// <summary>

    /// 狀態條件判斷委托

    /// </summary>

    public delegate bool StateTranslateEventHandler();

狀態類

    /// <summary>

    /// 狀態類

    /// </summary>

    public class State {

        /// <summary>

        /// 狀態內部事件

        /// </summary>

        public event StateFunctionEventHandler stateFunc;

        /// <summary>

        /// 狀態轉換事件<目標狀態,切換條件>

        /// </summary>

        public Dictionary<State,StateTranslateEventHandler> stateTrs;

        /// <summary>

        /// 狀態名稱

        /// </summary>

        /// <value>The name of the state.</value>

        public string stateName{get;private set;}

        /// <summary>

        /// 狀態運行中

        /// </summary>

        public bool isRun = false;

        /// <summary>

        /// 狀態內部事件執行間隔時間(毫秒)

        /// </summary>

        /// <value>The state function delta time.</value>

        public int stateFunctionDeltaTime{private get; set;}

        /// <summary>

        /// 狀態構造

        /// </summary>

        /// <param name="name">Name.</param>

        public State(string name)

        {

            stateName = name;

            stateTrs = new Dictionary<State, StateTranslateEventHandler> ();

            stateFunctionDeltaTime = 200;

            Thread th = new Thread (Update);

            th.Start ();

        }

        /// <summary>

        /// 狀態內部事件執行

        /// </summary>

        public void Update()

        {

            while(true)

            {

                if(!isRun)

                {

                    continue;

                }

                Thread.Sleep (stateFunctionDeltaTime);

                if(stateFunc != null)

                {

                    stateFunc();

                }

            }

        }

        /// <summary>

        /// 注冊切換事件.

        /// </summary>

        /// <param name="target">目標狀態.</param>

        /// <param name="conditional">條件事件.</param>

        public void RegisterTranslate(State target, StateTranslateEventHandler conditional)

        {

            try

            {

                stateTrs.Add (target, conditional);

            }

            catch(Exception ex)

            {

                Debug.LogError(ex.ToString());

            }

        }

    }

狀態管理類

    /// <summary>

    /// 狀態管理

    /// </summary>

    public class StateController : State {

        /// <summary>

        /// 狀態管理構造

        /// </summary>

        /// <param name="name">Name.</param>

        public StateController(string name) : base(name)

        {

            states = new Dictionary<string, State> ();

            stateparams = new Dictionary<string, object> ();

            stateFunc += CheckTranslate;

            isRun = true;

            Thread mainTh = new Thread (Update);

            mainTh.Start ();

        }

        /// <summary>

        /// 狀態字典

        /// </summary>

        Dictionary<string,State> states;

        /// <summary>

        /// 狀態切換參數字典

        /// </summary>

        Dictionary<string,object> stateparams;

        /// <summary>

        /// 當前狀態

        /// </summary>

        public State currentState;

        /// <summary>

        /// 添加狀態

        /// </summary>

        /// <returns>The state.</returns>

        /// <param name="statename">狀態名稱.</param>

        public State AddState(string statename)

        {

            State temp = new State (statename);

            states.Add (statename, temp);

            SetDefault (temp);

            return temp;

        }

        /// <summary>

        /// 添加狀態

        /// </summary>

        /// <param name="s">狀態.</param>

        public void AddState(State s)

        {

            states.Add (s.stateName, s);

            SetDefault (s);

        }

        /// <summary>

        /// 移除狀態

        /// </summary>

        /// <param name="statename">狀態名稱.</param>

        public void RemoveState(string statename)

        {

            states.Remove (statename);

        }

        /// <summary>

        /// 設置默認狀態

        /// </summary>

        /// <param name="s">S.</param>

        private void SetDefault (State s)

        {

            if(states.Count == 1)

            {

                currentState = s;

                s.isRun = true;

            }

        }

        /// <summary>

        /// 切換狀態

        /// </summary>

        /// <param name="name">狀態名稱.</param>

        public void TranslateState(string name)

        {

            if(states[name] != null)

            {

                currentState.isRun = false;

                currentState = states [name];

                states [name].isRun = true;

            }

        }

        /// <summary>

        /// 獲取狀態

        /// </summary>

        /// <returns>The state.</returns>

        /// <param name="statename">Statename.</param>

        public State GetState(string statename)

        {

            return states [statename];

        }

        /// <summary>

        /// 注冊參數

        /// </summary>

        /// <param name="paramName">參數名稱.</param>

        /// <param name="value">參數值.</param>

        public void RegisterParams(string paramName, int value)

        {

            stateparams.Add (paramName, value);

        }

        /// <summary>

        /// 注冊參數

        /// </summary>

        /// <param name="paramName">參數名稱.</param>

        /// <param name="value">參數值.</param>

        public void RegisterParams(string paramName, float value)

        {

            stateparams.Add (paramName, value);

        }

        /// <summary>

        /// 注冊參數

        /// </summary>

        /// <param name="paramName">參數名稱.</param>

        /// <param name="value">參數值.</param>

        public void RegisterParams(string paramName, string value)

        {

            stateparams.Add (paramName, value);

        }

        /// <summary>

        /// 獲取int類型參數

        /// </summary>

        /// <returns>The int parameters.</returns>

        /// <param name="paraName">Para name.</param>

        public int GetIntParams(string paraName)

        {

            return (int)stateparams [paraName];

        }

        /// <summary>

        /// 獲取float類型參數

        /// </summary>

        /// <returns>The float parameters.</returns>

        /// <param name="paraName">Para name.</param>

        public float GetFloatParams(string paraName)

        {

            return (float)stateparams [paraName];

        }

        /// <summary>

        /// 獲取string類型參數

        /// </summary>

        /// <returns>The string parameters.</returns>

        /// <param name="paraName">Para name.</param>

        public string GetStringParams(string paraName)

        {

            return (string)stateparams [paraName];

        }

        /// <summary>

        /// 設置int參數

        /// </summary>

        /// <param name="paraName">Para name.</param>

        /// <param name="value">Value.</param>

        public void SetIntParams(string paraName, int value)

        {

            stateparams[paraName] =value;

        }

        /// <summary>

        /// 設置float參數

        /// </summary>

        /// <param name="paraName">Para name.</param>

        /// <param name="value">Value.</param>

        public void SetFloatParams(string paraName, float value)

        {

            stateparams[paraName] =value;

        }

        /// <summary>

        /// 設置string參數

        /// </summary>

        /// <param name="paraName">Para name.</param>

        /// <param name="value">Value.</param>

        public void SetStringParams(string paraName, string value)

        {

            stateparams[paraName] =value;

        }

        /// <summary>

        /// 檢查狀態切換

        /// </summary>

        private void CheckTranslate()

        {

            foreach (var item in currentState.stateTrs) 

            {

                if(item.Value())

                {

                    TranslateState(item.Key.stateName);

                }

            }

        }

    }

實例應用

public class GameController : MonoBehaviour {

    //單例

    static StateController stateController;

    //外部測試

    public bool test = false;

    void Awake()

    {

        //1、實例化單例

        stateController = new StateController ("MainSc");

    }

    void Start()

    {

        //2、注冊狀態Idle

        State idle = stateController.AddState ("Idle");

        //2、注冊狀態Run

        State run = stateController.AddState ("Run");

        //3、注冊參數Speed,默認值0

        stateController.RegisterParams ("Speed", 0f);

        //4、idle內部事件

        idle.stateFunc += () => {

            Debug.Log(idle.stateName);

        };

        //4、run內部事件

        run.stateFunc += () => {

            Debug.Log(run.stateName);

        };

        //5、切換事件Idle --> Run

        idle.RegisterTranslate (run, () => {

            if(stateController.GetFloatParams("Speed") > 0.5f)

            {

                return true;

            }

            return false;

        });

        //5、切換事件Run --> Idle

        run.RegisterTranslate (idle, () => {

            if(stateController.GetFloatParams("Speed") <= 0.5f)

            {

                return true;

            }

            return false;

        });

    }

    void Update()

    {

        if (test)

        {

            //6、切換參數,調整狀態

            stateController.SetFloatParams("Speed",1);

        }

        else

        {

            stateController.SetFloatParams("Speed",0);

        }

    }

}

結束語

這個工具類中用到了多線程的處理,其中各個狀態的線程是持續執行的,所以后期還會繼續改進,如果讀者朋友有哪些更好的建議和意見,歡迎評論。

tags:
聲明:本站稿件版權均屬千鋒教育所有,未經許可不得擅自轉載。
10年以上業內強師集結,手把手帶你蛻變精英
請您保持通訊暢通,專屬學習老師24小時內將與您1V1溝通
免費領取
今日已有369人領取成功
劉同學 138****2860 剛剛成功領取
王同學 131****2015 剛剛成功領取
張同學 133****4652 剛剛成功領取
李同學 135****8607 剛剛成功領取
楊同學 132****5667 剛剛成功領取
岳同學 134****6652 剛剛成功領取
梁同學 157****2950 剛剛成功領取
劉同學 189****1015 剛剛成功領取
張同學 155****4678 剛剛成功領取
鄒同學 139****2907 剛剛成功領取
董同學 138****2867 剛剛成功領取
周同學 136****3602 剛剛成功領取
相關推薦HOT
色天使综合婷婷国产日韩AV| 欧美一区二区三区激情| А√天堂资源最新版在线官网| 99亚洲国产精品精华液| 岛国无码AⅤ片在线观看| 国产欧美在线观看不卡| 国产成人午夜精品影院| 好男人HD免费观看| 国产亚洲AV片在线观看播放按摩| 国产成人综合久久亚洲精品| 黑人大群体交免费视频| 免费黄色网站久久精品| 日韩中文无码有码免费视频| 日产一二三区别免费必看| 洗澡被公强奷30分钟视频| 欧美性大战XXXXX| 免费无码高潮流白浆视频| 日韩精品免费一线在线观看| 乱码人妻一区二区三区| 全棵女性艺术写真| 人妻精油按摩BD高清中文字幕 | 国产av一区二区三区| 狠狠做五月深爱婷婷天天综合| 国产精品妇女一二三区| 精品一区二区三区| 日本黄色免费在线观看| 日韩VS欧美VS亚洲VS无码| 亚洲AV无码日韩精品影片| 97人妻人人做人碰人人爽| 99精品无人区乱码1区2区3区 | 91人妻人人澡人人爽人人精品| 国产AV一二三无码影片| 久久熟女俱乐部五十路二区av| 色婷婷综合久久久久中文一区二区| 亚洲乱码日产精品BD在线| GOGO全球高清专业大尺度摄影| 国产亚洲精品黑人粗大精选| 欧美男男作爱GAYWWW| 性姿势108式大全图解| 98在线视频噜噜噜国产| 国产亚洲精品第一综合另类| 欧美群妇大交乱视| 亚洲高清国产拍精品动图| 啊灬啊灬啊灬快高潮视频| 精品日产卡一卡二卡927| 日韩无人区码卡二卡3卡一| 夜夜躁狠狠躁日日躁视频| 欲色欲色天天天WWW| 高清国产AV一区二区三区| 久久夜色精品国产亚洲| 无码精品一区二区三区在线| 777成了乱人视频| 黑人刚破完处就三P| 日本真人边吃奶边做爽动态图| 亚洲中文字幕无码AV在线| 丰满少妇人妻无码| 男女啪啪摸下面喷水网站| 亚洲A∨无码男人的天堂| 啊灬啊灬啊灬啊灬高潮了| 久久久噜噜噜久久中文福利| 无码熟妇人妻AV影片在线| WWW.らだ天堂中文在线| 久久精品久久久久久噜噜| 免费看漫画在线成人漫画| 午夜无码视频在线观看网站| А√最新版地址在线天堂| 久久久久久九九99精品| 无人区一线二线三线乱码| 爱丫爱丫影院在线| 乱人伦人妻中文字幕不卡| 亚洲AV无码久久精品色欲| 嗯…啊 摸 湿 奶头免费视频| 免费无码久久成人网站入口| 亚洲精品中文字幕乱码| 国产精品久久久影视青草| 日本熟妇色XXXXXBBB日本| 中文字幕日韩精品无码内射| 粗大黑人巨茎大战欧美成人| 妺妺窝人体色WWW看人体| 亚洲精品中文字幕无码专区| 国产精品久久无码不卡黑寡妇| 人体内射精一区二区三区| 亚洲AV人无码激艳猛片| 大荫蒂又大又长又硬又紧| 免费观看电视在线高清 | 无码一区二区三区中文字幕| 草莓视频CAOMEI888| 欧美精品天堂一区二区不卡| 有人有在线观看的片吗WWW| 精品第一国产综合精品AⅤ| 无码人妻av免费一区二区三区| 草莓丝瓜芭乐鸭脖奶茶搭配食物| 农民人伦一区二区三区| 再深点灬舒服灬太大了添动视频 | 男生把QQ放进女生的QQ里在线| 夜夜高潮夜夜爽高清视频一| 精品久久久无码人妻中文字幕豆芽| 无码精品人妻一区二区| 丰满乳乱亲伦小说| 日韩人妻无码一区二区三区久久 | 在公交车上弄到高C了公交车最后| 精品国产三级A∨在线| 亚洲AV无码久久精品成人| 国产区精品一区二区不卡中文| 婷婷妺妺窝人体色www久久| 亚洲最大av在线| 精品欧洲AV无码一区二区| 亚洲AV午夜福利精品一区人妖 | 亚洲熟伦熟妇AV无码春| 花色98堂新网名内容与理念 | 亚洲A成人片在线播放| 亚洲AV无码乱码在线观看富二代| 国产精品爽爽ⅤA在线观看| 天堂中文最新版在线中文| 公侵犯玩弄漂亮人妻优| 伸进衣服里吃奶捏胸视频| 曰韩精品无码一区二区三区视频| 亚洲精品中文字幕久久久久下载 | 国产精品丝袜高跟鞋| 天天躁夜夜躁AV天天爽| 国产成人麻豆亚洲综合无码精品| 国产色视频一区二区三区QQ号| 老妇擦她毛荫荫的玥户| 幼儿稀缺区超清幼儿做的网站| 久久午夜无码免费| 伊人热热久久原色播放WWW| 两个病娇男友轮流爱我资源 | 伊人久久大香线蕉AV一区| 久久久久夜夜夜精品国产| 一区二区三区欧美| 民工把我奶头掏出来了怎么办| 18禁自慰网址进入| 精品少妇人妻AV免费久久久| 亚洲日本VA中文字幕| 久久久无码精品国产一区| 正在播放国产对白孕妇作爱| 黑人巨大超大VIDEOSGRA| 亚洲国产成人精品女人久久久| 精品人妻无码中字系列| 一本加勒比HEZYO无码专区| 美女粉嫩饱满的一线天MP4| AV无码人妻一区二区三区在线| 人人妻人人澡人人爽| 公交车上穿短裙被狂C| 无码熟妇人妻AV在线影片| 韩国免费A级毛片| 夜夜高潮次次欢爽AV女| 欧美肥妇多毛BBW| 在线观看日本亚洲一区| 男生把QQ放进女生的QQ里韩剧| ているの天堂资源WWW| 色综合久久蜜芽国产精品| 国产熟妇一区二区三区AⅤ在线| 亚洲国产精品久久久就秋霞| 久久亚洲精品AB无码播放| 99久久精品美女高潮喷水| 日产乱码一二三区别免费观看| 国产精品99久久久久久人| 亚洲国产精品无码久久久动漫| 国产精品自产Av一区二区三区| 亚洲AV成人一区二区三区在线播| 久久久国产精品一区二区18禁| 99久久久无码国产精品性| 色婷婷日日躁夜夜躁| 国产裸体XXXX视频在线播放 | 天天澡天天添天天摸97影院| 韩国三级丰满少妇高潮| 又大又长粗又爽又黄少妇毛片| 情人伊人久久综合亚洲| 国产成人午夜福利不卡在线观看 | AAA女人18毛片水真多| 少妇丰满爆乳被呻吟进入| 狠狠色丁香婷婷久久综合| 中文字幕人妻AV一区二区| 色一情一乱一伦麻豆| 亚洲自偷自拍熟女另类| 国产精品无码久久久久| 亚洲一二三四2021不卡| 精品国产污污免费网站AⅤ| 最新无码人妻在线不卡| 视频一区二区三区在线| 精品国产VA久久久久久久冰| 99国产精品白浆无码流出| 未满十八18禁止午夜免费网站| 久久99精品久久久久免费| HENNESSY女RAPPER| 小13箩利洗澡无码免费视频| 久久综合伊人77777麻豆| 从你的全世界路过| 亚洲日韩乱码1区二区| 人妻无码一区二区| 激情 亚洲 成人小说 激情| CHINESE中年熟妇FREE| 亚洲AV成人片色在线观看| 女儿国在线观看免费版高清| 国产成人无码AV在线影院 | 久久久无码精品午夜| 隔壁老王国产在线精品| 诱女偷伦初尝云雨H| 四虎在线观看视频9E9|