Unity3D有限状态机(FSM)学习笔记【4】FiniteStateMachine类

本系列笔记转载自游戏蛮牛专栏作家Jackel的论坛文章,详细介绍了FSM的创建与使用,特与众分享。链接:http://www.manew.com/thread-37136-1-1.html

该类是对外开放的,主要用于外界的调用,独立封装,不继承Mono。该类定义一个栈,用于存放FSState,通过Update进行状态的切换。对栈的管理及Pop和Push操作、状态机的注册。该类声明了三个重要的委托。代码如下:

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 FSState CurrentState
	{
		get
		{
			if( mStateStack.Count == 0 )
			{
				return null;	
			}
			return mStateStack.Peek();
		}
	}
	
	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 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 );
	}
	
	public 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 );
	}
}

一、委托

这三个委托主要用于状态的转换。

1、EnterState


2、PushState


3、PopState


二、数据存取

1、protected Dictionary<string, FSState> mStates


2、protected Stack<FSState>    mStateStack

栈用于状态机的注册,对Stack的操作主要是Pop和Push函数。


三、事件触发

事件的触发,主要是对Trigger进行了重载,实现不同状态事件的触发。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值