【转】有限状态机(FSM)学习总结C#
FSM(Finite State Machine有限狀態機)可以理解成是對行為邏輯的抽象,就好象人在生活中會做出各種行為,例如吃飯、睡覺等,這些所有我們都看作是“行為”的分支,由大腦決定每種行為具體是什么實施。在整個FSM架構中,其實與上面解釋一致,首先有一個狀態基類stateObject,里面有三個方法,分別是狀態前、狀態中、狀態后。所有具體行為都要繼承這個基類,在這三個方法中具體實現各種方法的邏輯。然后,需要一個stateManager(大腦)狀態管理類來管理這些狀態,特別注意的是里面changeState方法,他是狀態跳轉的關鍵。至于如果存儲各種狀態,你可以用list類 ,字典類等等。有限狀態機就是把一個對象的行為分解成為易于處理的“塊”或“狀態”。
? ?例如將人的行為抽象成3個,分別是吃飯、睡覺、上班。上班族,只有吃飯、睡覺、上班三種行為,我們把這三種行為放進我們的大腦,即stateManager。那我們從什么行為開始呢?(其實這里就是initState),隨便挑一個,默認為睡覺。之前說過,每個行為都有三個狀態(前、中、后),當我們進入睡覺行為時,首先進入的是睡覺前狀態(該狀態只執行一次),然后進入睡覺中,真正的邏輯是在這里執行的,它會不停檢查什么時候睡醒了,符合條件后跳到其他狀態,當要進行跳轉時,還會執行一次睡覺后狀態,其實前、后狀態我理解成當要執行或結束某種行為時,你要額外做的事情。例如,睡覺前我要帶個眼罩。(放到游戲開發里可以進行一些賦值操作,或者調用其他類的方法,例如一些特效)。因為它編程快速簡單,易于調試,性能高,與人類思維相似從而具有:1.便于梳理狀態關系,2.使用靈活,3.容易修改
FSM的優點就是因為它編程快速,簡單,易于調試,性能高,與人類思維相似。
以下是一個自己寫的實例代碼,可供大家參考
首先創建一個抽象狀態基類,里面有3個抽象方法,分別是進入狀態,離開狀態,更新狀態的方法
?
using System.Collections; using System.Collections.Generic; using UnityEngine;public abstract class StateObject {//狀態控制機protected StateManger sm;//構造函數public StateObject(StateManger _sm){sm = _sm;}//進入狀態方法public abstract void EnterState();//離開狀態方法public abstract void ExitState();//更新狀態方法public abstract void UpdateState();}?
然后根據具體的情況創建具體的狀態類(繼承自狀態基類),我這里實現了3個具體的狀態類,分別是人物默認狀態,移動狀態,死亡狀態
默認狀態方法
?
using System.Collections; using System.Collections.Generic; using UnityEngine;public class IdleState : StateObject {public IdleState(StateManger _sm):base(_sm){} //進入狀態方法public override void EnterState(){Debug.Log("進入待定狀態");} //離開狀態方法public override void ExitState(){Debug.Log("離開待定狀態");} //更新狀態方法public override void UpdateState(){Debug.Log("更新待定狀態");if (Input.GetKeyDown(KeyCode.M)){sm.ChangeState("Move");}else if (Input.GetKeyDown(KeyCode.D)){sm.ChangeState("Die");}}}?
移動狀態方法
?
using System.Collections; using System.Collections.Generic; using UnityEngine;public class MoveState : StateObject {public MoveState(StateManger _sm) :base(_sm){}public override void EnterState(){Debug.Log("進入移動狀態");}public override void ExitState(){Debug.Log("離開移動狀態");}public override void UpdateState(){Debug.Log("更新移動狀態");if (Input.GetKeyDown(KeyCode.D)){sm.ChangeState("Die");}else if(Input.GetKeyDown(KeyCode.I)){sm.ChangeState("Idle");}} }?
死亡狀態方法
?
using System.Collections; using System.Collections.Generic; using UnityEngine;public class DieState : StateObject {public DieState(StateManger _sm):base(_sm){}public override void EnterState(){Debug.Log("進入死亡狀態");}public override void ExitState(){Debug.Log("離開死亡狀態");}public override void UpdateState(){Debug.Log("更新死亡狀態");if (Input.GetKeyDown(KeyCode.I)){sm.ChangeState("Idle");}} }?
然后,需要一個stateManager(大腦)狀態管理類來管理這些狀態,特別注意的是里面changeState方法,他是狀態跳轉的關鍵,需要放在Update函數中,因為需要不斷檢測當前的狀態,檢測是否跳轉
?
using System.Collections; using System.Collections.Generic; using UnityEngine;public class StateManger {//利用字典存儲各種狀態Dictionary<string, StateObject> Dic = new Dictionary<string, StateObject>();//當前狀態StateObject currentstate;//注冊狀態public void Region(string statename,StateObject state){if (!Dic.ContainsKey(statename)){Dic.Add(statename,state);}}//設置默認狀態public void SetDefat(string statename){if (Dic.ContainsKey(statename)){currentstate = Dic[statename];currentstate.EnterState();}}//改變狀態public void ChangeState(string statename){if (Dic.ContainsKey(statename)){if (currentstate!=null){currentstate.ExitState();currentstate = Dic[statename];currentstate.EnterState();}}}//更新狀態public void UpdateState(){if (currentstate!=null){currentstate.UpdateState();}}}?
這樣一個簡單的有限狀態機就寫好了,然后我們可以在Unity里面利用一個實例來測試一下,我寫了一個控制物體狀態的腳本
?
using System.Collections; using System.Collections.Generic; using UnityEngine;public class TestFsm : MonoBehaviour {//添加一個狀態機StateManger stm = new StateManger();void Start(){//注冊狀態stm.Region("Idle", new IdleState(stm));stm.Region("Die", new DieState(stm));stm.Region("Move", new MoveState(stm)); //設置默認狀態stm.SetDefat("Idle");}// Update is called once per framevoid Update(){ //更新狀態的方法stm.UpdateState();} }以上就是本人學習FSM的一點總結,如果有什么不對的地方,敬請大家指出,大家一起學習進步。
總結
以上是生活随笔為你收集整理的【转】有限状态机(FSM)学习总结C#的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 发债中签后什么时候卖?发债卖不出去是什么
- 下一篇: 新债中一签如何操作?新债中签后几时卖