Unity3D架构系列之- FSM有限状态机设计二

来源:互联网 发布:淘宝客佣金谁给的 编辑:程序博客网 时间:2024/05/18 00:38

原文:http://www.manew.com/thread-37244-1-1.html


在设计一中,我们把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函数。代码如下:

</pre><pre>

<pre name="code" class="csharp">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类就封装完了。

0 0
原创粉丝点击