120 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C#
		
	
	
	
			
		
		
	
	
			120 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C#
		
	
	
	
| using System;
 | |
| using System.Reflection;
 | |
| using System.Collections;
 | |
| using System.Collections.Generic;
 | |
| using UnityEngine;
 | |
| 
 | |
| public class FSM<T>
 | |
| {
 | |
|     public string CurrentState => mCurrentState != null ? mCurrentState.GetType().ToString() : "";
 | |
| 
 | |
|     private Dictionary<Type, BaseState<T>> mStateDic;
 | |
|     private T mMaster;
 | |
|     private BaseState<T> mCurrentState;
 | |
|     private bool mActive;
 | |
| 
 | |
|     public FSM(T pMaster)
 | |
|     {
 | |
|         mMaster = pMaster;
 | |
|         mStateDic = new Dictionary<Type, BaseState<T>>();
 | |
|         mActive = true;
 | |
|     }
 | |
| 
 | |
|     public void ChangeState(Type pStateType = null)
 | |
|     {
 | |
|         if (pStateType == null)//change to empty
 | |
|         {
 | |
|             if (mCurrentState != null)
 | |
|                 mCurrentState.ExitState(null);
 | |
|             mCurrentState = null;
 | |
| 
 | |
|             return;
 | |
|         }
 | |
| 
 | |
|         BaseState<T> tNextState = null;
 | |
|         if (pStateType != null)
 | |
|         {
 | |
|             if (!mStateDic.ContainsKey(pStateType))
 | |
|             {
 | |
|                 object tInstance = pStateType.Assembly.CreateInstance(pStateType.Name);
 | |
|                 if (tInstance is BaseState<T>)
 | |
|                 {
 | |
|                     tNextState = tInstance as BaseState<T>;
 | |
|                     tNextState.SetFSM(this);
 | |
|                     tNextState.SetMaster(mMaster);
 | |
|                     mStateDic.Add(pStateType, tNextState);
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     Debug.LogError("State Class : " + pStateType.Name + " is not a " + typeof(BaseState<T>).Name + "!");
 | |
|                 }
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 tNextState = mStateDic[pStateType];
 | |
|             }
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             Debug.LogError("State Class : " + pStateType.Name + " is not found!");
 | |
|         }
 | |
| 
 | |
|         if (tNextState != null && tNextState != mCurrentState)
 | |
|         {
 | |
|             if (mCurrentState != null)
 | |
|                 mCurrentState.ExitState(tNextState.GetType());
 | |
|             tNextState.EnterState(mCurrentState?.GetType());
 | |
|             mCurrentState = tNextState;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     public void Execute(float pDeltaTime)
 | |
|     {
 | |
|         if (!mActive)
 | |
|             return;
 | |
| 
 | |
|         if (mCurrentState != null)
 | |
|             mCurrentState.ExecuteState(pDeltaTime);
 | |
|     }
 | |
| 
 | |
|     public void SetActive(bool pActive)
 | |
|     {
 | |
|         mActive = pActive;
 | |
|     }
 | |
| }
 | |
| 
 | |
| public class BaseState<T>
 | |
| {
 | |
|     protected T mMaster;
 | |
|     protected FSM<T> mFSM;
 | |
| 
 | |
|     public void SetFSM(FSM<T> pFSM)
 | |
|     {
 | |
|         mFSM = pFSM;
 | |
|     }
 | |
| 
 | |
|     public void SetMaster(T pMaster)
 | |
|     {
 | |
|         mMaster = pMaster;
 | |
|     }
 | |
| 
 | |
|     public virtual void EnterState(Type pLastState)
 | |
|     {
 | |
| 
 | |
|     }
 | |
| 
 | |
|     public virtual void ExitState(Type pNextState)
 | |
|     {
 | |
| 
 | |
|     }
 | |
| 
 | |
|     public virtual void ExecuteState(float pDeltaTime)
 | |
|     {
 | |
| 
 | |
|     }
 | |
| 
 | |
|     protected void ChangeState(Type pType)
 | |
|     {
 | |
|         mFSM.ChangeState(pType);
 | |
|     }
 | |
| } |