1. 程式人生 > >Unity3D有限狀態機(FSM)學習筆記【3】FSState類

Unity3D有限狀態機(FSM)學習筆記【3】FSState類

本系列筆記轉載自遊戲蠻牛專欄作家Jackel的論壇文章,詳細介紹了FSM的建立與使用,特與眾分享。連結:http://www.manew.com/thread-37136-1-1.html

該類主要是狀態的基本操作及事件的新增與觸發。程式碼如下:

using System;
using System.Collections;
using System.Collections.Generic;

public class FSState
{
	protected FiniteStateMachine.EnterState mEnterDelegate;
	protected FiniteStateMachine.PushState  mPushDelegate;
	protected FiniteStateMachine.PopState	mPopDelegate;
	
	protected IState mStateObject;
	protected string mStateName;
	protected FiniteStateMachine mOwner;
	protected Dictionary<string, FSEvent> mTranslationEvents;
	
	public FSState( IState obj, FiniteStateMachine owner, string name, FiniteStateMachine.EnterState e, FiniteStateMachine.PushState pu, FiniteStateMachine.PopState po )
	{
		mStateObject 	= obj;
		mStateName		= name;
		mOwner			= owner;
		mEnterDelegate	= e;
		mPushDelegate	= pu;
		mPopDelegate	= po;
		mTranslationEvents = new Dictionary<string, FSEvent>();
	}
	
	public IState StateObject
	{
		get { return mStateObject; }
	}
	
	public string StateName
	{
		get { return mStateName; }
	}
	
	public FSEvent On( string eventName )
	{
		FSEvent newEvent = new FSEvent( eventName, null, this, mOwner, mEnterDelegate, mPushDelegate, mPopDelegate );
		mTranslationEvents.Add( eventName, newEvent );
		return newEvent;
	}
	
	public void Trigger( string name )
	{
		mTranslationEvents[ name ].Execute( null, null, null );
	}
	
	public void Trigger( string eventName, object param1 )
	{
		mTranslationEvents[ eventName ].Execute( param1, null, null );	
	}
	
	public void Trigger( string eventName, object param1, object param2 )
	{
		mTranslationEvents[ eventName ].Execute( param1, param2, null );	
	}
	
	public void Trigger( string eventName, object param1, object param2, object param3 )
	{
		mTranslationEvents[ eventName ].Execute( param1, param2, param3 );	
	}
	
	public FSState On<T>( string eventName, Func<T,bool> action )
	{
		FSEvent newEvent = new FSEvent( eventName, null, this, mOwner, mEnterDelegate, mPushDelegate, mPopDelegate );
		newEvent.mAction = delegate( object o1, object o2, object o3 )
		{
			T param1;
			try { param1 = (T)o1; }
			catch { param1 = default(T); }
			action( param1 );
			return true;
		};
		mTranslationEvents.Add( eventName, newEvent );
		return this;
	}
	
	public FSState On<T>( string eventName, Action<T> action )
	{
		FSEvent newEvent = new FSEvent( eventName, null, this, mOwner, mEnterDelegate, mPushDelegate, mPopDelegate );
		newEvent.mAction = delegate( object o1, object o2, object o3 )
		{
			T param1;
			try{ param1 = (T)o1; }
			catch{ param1 = default(T); }
			action( param1 );
			return true;
		};
		mTranslationEvents.Add( eventName, newEvent );
		return this;
	}
	
	public FSState On<T1,T2>( string eventName, Func<T1,T2,bool> action)
	{
		FSEvent newEvent = new FSEvent( eventName, null, this, mOwner, mEnterDelegate, mPushDelegate, mPopDelegate );
		newEvent.mAction = delegate( object o1, object o2, object o3 )
		{
			T1 param1;
			T2 param2;
			try{ param1 = (T1)o1; } catch { param1 = default(T1); }
			try{ param2 = (T2)o2; } catch { param2 = default(T2); }
			action( param1, param2 );
			return true;
		};
		mTranslationEvents.Add( eventName, newEvent );
		return this;
	}
	
	public FSState On<T1,T2>( string eventName, Action<T1,T2> action )
	{
		FSEvent newEvent = new FSEvent( eventName, null, this, mOwner, mEnterDelegate, mPushDelegate, mPopDelegate );
		newEvent.mAction = delegate( object o1, object o2, object o3 )
		{
			T1 param1;
			T2 param2;
			try{ param1 = (T1)o1; } catch { param1 = default(T1); }
			try{ param2 = (T2)o2; } catch { param2 = default(T2); }
			action( param1, param2 );
			return true;
		};
		
		mTranslationEvents.Add( eventName, newEvent );
		return this;
	}
	
	public FSState On<T1,T2,T3>( string eventName, Func<T1,T2,T3,bool> action )
	{
		FSEvent newEvent = new FSEvent( eventName, null, this, mOwner, mEnterDelegate, mPushDelegate, mPopDelegate );
        newEvent.mAction = delegate (object o1, object o2, object o3) 
		{
            T1 param1;
            T2 param2;
            T3 param3;
            try { param1 = (T1)o1; } catch { param1 = default(T1); }
            try { param2 = (T2)o2; } catch { param2 = default(T2); }
            try { param3 = (T3)o3; } catch { param3 = default(T3); }
            action(param1, param2, param3);
            return true;
	    };
        mTranslationEvents.Add(eventName, newEvent);
        return this;	
	}
	
	public FSState On<T1,T2,T3>( string eventName, Action<T1,T2,T3> action )
	{
		FSEvent newEvent = new FSEvent( eventName, null, this, mOwner, mEnterDelegate, mPushDelegate, mPopDelegate );
        newEvent.mAction = delegate (object o1, object o2, object o3) 
		{
            T1 param1;
            T2 param2;
            T3 param3;
            try { param1 = (T1)o1; } catch { param1 = default(T1); }
            try { param2 = (T2)o2; } catch { param2 = default(T2); }
            try { param3 = (T3)o3; } catch { param3 = default(T3); }
            action(param1, param2, param3);
            return true;
        };
        mTranslationEvents.Add(eventName, newEvent);
        return this;
	}
}
該類定義了FiniteStateMachine中的三個委託,是一個獨立的類,不繼承Mono。FiniteStateMachine下一篇講解

一、委託

1、FiniteStateMachine.EnterState

2、FiniteStateMachine.PushState

3、FiniteStateMachine.PopState

二、事件加入

事件加入有兩個重要函式

1、On

public FSEvent On( string eventName )
{
	FSEvent newEvent = new FSEvent( eventName, null, this, mOwner, mEnterDelegate, mPushDelegate, mPopDelegate );
	mTranslationEvents.Add( eventName, newEvent );
	return newEvent;
}
該方法用於將事件的名字和事件加入到Dictionary中。

2、Trigger

public void Trigger( string name )
{
	mTranslationEvents[ name ].Execute( null, null, null );
}
改方法用於從Dictionary中取出事件的觸發函式,去執行相應的操作。