您好,登錄后才能下訂單哦!
有限狀態(tài)機(jī)主要是用于狀態(tài)之間的切換,狀態(tài)之間的切換也可以通過Switch Case或者if else實(shí)現(xiàn)。由于使用二者實(shí)現(xiàn)主要是對(duì)用用戶擴(kuò)展不是很方便,所以就有了有限狀態(tài)機(jī)的概念。 有限狀態(tài)機(jī)主要是用于不同的狀態(tài)頻繁的切換。那在Unity中我們?nèi)绾味x有限狀態(tài)機(jī)?其實(shí)有限狀態(tài)機(jī)主要包括三部分,切換狀態(tài),進(jìn)入狀態(tài),退出狀態(tài)。接下來我們就利用Unity實(shí)現(xiàn)有限狀態(tài)機(jī)并給大家展示如何應(yīng)用。
首先我們定義FSMState.cs腳本,我們通過委托對(duì)函數(shù)狀態(tài)進(jìn)行切換.代碼如下:
using System;
using System.Collections.Generic;
namespace FSM
{
public class FSMState
{
private int stateName;
private Dictionary<int, int> transitions = new Dictionary<int, int>();
//設(shè)置狀態(tài)名字
public void SetStateName(int newStateName)
{
this.stateName = newStateName;
}
//獲取狀態(tài)名字
public int GetStateName()
{
return this.stateName;
}
//加入狀態(tài)
public void AddTransition(int transition, int outputState)
{
this.transitions[transition] = outputState;
}
//使用狀態(tài)
public int ApplyTransition(int transition)
{
int result = this.stateName;
if (this.transitions.ContainsKey(transition))
{
result = this.transitions[transition];
}
return result;
}
}
}
以上的類定義的是狀態(tài)。下面我們定義對(duì)外接口,有限狀態(tài)機(jī)FStateMachine.cs腳本
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
namespace FSM
{
public class FStateMachine
{
//聲明了一個(gè)委托用于狀態(tài)之間的切換
public delegate void OnStateChangeDelegate(int fromStateName, int toStateName);
private List<FSMState> states = new List<FSMState>();
private volatile int currentStateName;
public FiniteStateMachine.OnStateChangeDelegate onStateChange;
private object locker = new object();
//增加狀態(tài)
public void AddState(object st)
{
int stateName = (int)st;
FSMState fSMState = new FSMState();
fSMState.SetStateName(stateName);
this.states.Add(fSMState);
}
//增加所有狀態(tài)
public void AddAllStates(Type statesEnumType)
{
IEnumerator enumerator = Enum.GetValues(statesEnumType).GetEnumerator();
try
{
while (enumerator.MoveNext())
{
object current = enumerator.Current;
this.AddState(current);
}
}
finally
{
IDisposable disposable;
if ((disposable = (enumerator as IDisposable)) != null)
{
disposable.Dispose();
}
}
}
//該函數(shù)是表示從from到to的轉(zhuǎn)換
public void AddStateTransition(object from, object to, object tr)
{
int num = (int)from;
int outputState = (int)to;
int transition = (int)tr;
FSMState fSMState = this.FindStateObjByName(num);
fSMState.AddTransition(transition, outputState);
}
public int ApplyTransition(object tr)
{
object obj = this.locker;
Monitor.Enter(obj);
int result;
try
{
int transition = (int)tr;
int num = this.currentStateName;
this.currentStateName = this.FindStateObjByName(this.currentStateName).ApplyTransition(transition);
if (num != this.currentStateName)
{
if (this.onStateChange != null)
{
this.onStateChange(num, this.currentStateName);
}
}
result = this.currentStateName;
}
finally
{
Monitor.Exit(obj);
}
return result;
}
public int GetCurrentState()
{
object obj = this.locker;
Monitor.Enter(obj);
int result;
try
{
result = this.currentStateName;
}
finally
{
Monitor.Exit(obj);
}
return result;
}
public void SetCurrentState(object state)
{
int toStateName = (int)state;
if (this.onStateChange != null)
{
this.onStateChange(this.currentStateName, toStateName);
}
this.currentStateName = toStateName;
}
private FSMState FindStateObjByName(object st)
{
int num = (int)st;
FSMState result;
foreach (FSMState current in this.states)
{
if (num.Equals(current.GetStateName()))
{
result = current;
return result;
}
}
result = null;
return result;
}
}
}
以上定義的是有限狀態(tài)機(jī)類,那接下來我給大家展示如何實(shí)現(xiàn)。
我們可以先初始化狀態(tài),那如何初始化,看下面的函數(shù):
private void InitStates()
{
this.fsm = new FStateMachine();
this.fsm.AddAllStates(typeof(TCPSocketLayer.States));
this.fsm.AddStateTransition(TCPSocketLayer.States.Disconnected, TCPSocketLayer.States.Connecting, TCPSocketLayer.Transitions.StartConnect);
this.fsm.AddStateTransition(TCPSocketLayer.States.Connecting, TCPSocketLayer.States.Connected, TCPSocketLayer.Transitions.ConnectionSuccess);
this.fsm.AddStateTransition(TCPSocketLayer.States.Connecting, TCPSocketLayer.States.Disconnected, TCPSocketLayer.Transitions.ConnectionFailure);
this.fsm.AddStateTransition(TCPSocketLayer.States.Connected, TCPSocketLayer.States.Disconnected, TCPSocketLayer.Transitions.Disconnect);
this.fsm.SetCurrentState(TCPSocketLayer.States.Disconnected);
}
首先實(shí)例化一個(gè)有限狀態(tài)機(jī)對(duì)象fsm,然后我們做了一個(gè)枚舉值TCPSocketLayer,然后將其加入狀態(tài)轉(zhuǎn)換函數(shù)AddAllStates,比如AddStateTransition(TCPSocketLayer.States.Disconnected, TCPSocketLayer.States.Connecting, TCPSocketLayer.Transitions.StartConnect);
表示是從Disconnected到Connecting之間的轉(zhuǎn)換。
函數(shù)的末尾是設(shè)置當(dāng)前狀態(tài)為Disconnected。
如果我們關(guān)閉連接,我們可以使用Disconnect狀態(tài),如下函數(shù)所示:
public void Kill()
{
this.fsm.ApplyTransition(TCPSocketLayer.Transitions.Disconnect);
this.connection.Close();
}
總結(jié)一下:剛開始我們要把所有的狀態(tài)之間的切換加入到表里,后面我們就可以隨意的使用狀態(tài)了。以上主要是利用網(wǎng)絡(luò)通信舉的事例。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。