在设计一中,我们把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进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。