您好,登錄后才能下訂單哦!
在設計一中,我們把IState類設計了一下,接下來,我們寫一下FiniteStateMachine這個類,這個類主要的作用就是對于外界調用,這個類是獨立封裝的,不繼承Mono。這個類的功能是提供一個棧,用于存放FSState,還有通過Update進行狀態的切換,以及對棧的管理,Pop和Push操作以及狀態的注冊。最重要的一點是聲明了三個委托函數代碼如下:
public delegate void EnterState(string stateName); public delegate void PushState(string stateName, string lastStateName); public delegate void PopState();
主要是用于狀態之間的切換。定義了Dictionary和Stack,前者用于State注冊,后者是狀態切換。代碼如下:
protected Dictionary<string, FSState> mStates; protected Stack<FSState> mStateStack;
對應的相關處理函數如下:
public void Register(string stateName, IState stateObject) { if (mStates.Count == 0) mEntryPoint = stateName; mStates.Add(stateName, new FSState(stateObject, this, stateName, Enter, Push, Pop)); }
用于狀態機的注冊,對Stack的操作是如下兩個函數,一個是Pop,一個是Push函數。代碼如下:
public void Push(string newState) { string lastName = null; if (mStateStack.Count > 1) { lastName = mStateStack.Peek().StateName; } Push(newState, lastName); } protected void Push(string stateName, string lastStateName) { mStateStack.Push(mStates[stateName]); mStateStack.Peek().StateObject.OnEnter(lastStateName); } public void Pop() { Pop(null); } protected string Pop(string newName) { FSState lastState = mStateStack.Peek(); string newState = null; if (newName == null && mStateStack.Count > 1) { int index = 0; foreach (FSState item in mStateStack) { if (index++ == mStateStack.Count - 2) { newState = item.StateName; } } } else { newState = newName; } string lastStateName = null; if (lastState != null) { lastStateName = lastState.StateName; lastState.StateObject.OnExit(newState); } mStateStack.Pop(); return lastStateName; }
下面增加了狀態觸發消息事件,代碼如下:
public void Trigger(string eventName) { CurrentState.Trigger(eventName); } public void Trigger(string eventName, object param1) { CurrentState.Trigger(eventName, param1); } public void Trigger(string eventName, object param1, object param2) { CurrentState.Trigger(eventName, param1, param2); } public void Trigger(string eventName, object param1, object param2, object param3) { CurrentState.Trigger(eventName, param1, param2, param3); }
最后把FiniteStateMachine核心的功能給大家介紹完了,下面奉上整個類的代碼:
using UnityEngine; using System.Collections; using System.Collections.Generic; public class FiniteStateMachine { public delegate void EnterState(string stateName); public delegate void PushState(string stateName, string lastStateName); public delegate void PopState(); protected Dictionary<string, FSState> mStates; protected string mEntryPoint; protected Stack<FSState> mStateStack; public FiniteStateMachine() { mStates = new Dictionary<string, FSState>(); mStateStack = new Stack<FSState>(); mEntryPoint = null; } public void Update() { if (CurrentState == null) { mStateStack.Push(mStates[mEntryPoint]); CurrentState.StateObject.OnEnter(null); } CurrentState.StateObject.OnUpdate(); } public void Register(string stateName, IState stateObject) { if (mStates.Count == 0) mEntryPoint = stateName; mStates.Add(stateName, new FSState(stateObject, this, stateName, Enter, Push, Pop)); } public FSState State(string stateName) { return mStates[stateName]; } public void EntryPoint(string startName) { mEntryPoint = startName; } public FSState CurrentState { get { if (mStateStack.Count == 0) return null; return mStateStack.Peek(); } } public void Enter(string stateName) { Push(stateName, Pop(stateName)); } public void Push(string newState) { string lastName = null; if (mStateStack.Count > 1) { lastName = mStateStack.Peek().StateName; } Push(newState, lastName); } protected void Push(string stateName, string lastStateName) { mStateStack.Push(mStates[stateName]); mStateStack.Peek().StateObject.OnEnter(lastStateName); } public void Pop() { Pop(null); } protected string Pop(string newName) { FSState lastState = mStateStack.Peek(); string newState = null; if (newName == null && mStateStack.Count > 1) { int index = 0; foreach (FSState item in mStateStack) { if (index++ == mStateStack.Count - 2) { newState = item.StateName; } } } else { newState = newName; } string lastStateName = null; if (lastState != null) { lastStateName = lastState.StateName; lastState.StateObject.OnExit(newState); } mStateStack.Pop(); return lastStateName; } public void Trigger(string eventName) { CurrentState.Trigger(eventName); } public void Trigger(string eventName, object param1) { CurrentState.Trigger(eventName, param1); } public void Trigger(string eventName, object param1, object param2) { CurrentState.Trigger(eventName, param1, param2); } public void Trigger(string eventName, object param1, object param2, object param3) { CurrentState.Trigger(eventName, param1, param2, param3); } }
上面整個FSMStateMachine類就封裝完了,要知后事如何?且看系列三的講解。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。