143 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			C#
		
	
	
	
			
		
		
	
	
			143 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			C#
		
	
	
	
| using UnityEngine;
 | |
| using System;
 | |
| using System.Collections.Generic;
 | |
| 
 | |
| public class SimpleStateMachine : MonoBehaviour
 | |
| {
 | |
|     public bool DebugGui;
 | |
|     public Vector2 DebugGuiPosition;
 | |
| 
 | |
|     public string DebugGuiTitle = "Simple Machine";
 | |
| 
 | |
|     protected Enum queueCommand;
 | |
| 
 | |
|     void OnGUI()
 | |
|     {
 | |
|         if (DebugGui)
 | |
|         {
 | |
|             GUI.Box(new Rect(DebugGuiPosition.x, DebugGuiPosition.y, 200, 50), DebugGuiTitle);
 | |
| 
 | |
|             GUI.TextField(new Rect(DebugGuiPosition.x + 10, DebugGuiPosition.y + 20, 180, 20), string.Format("State: {0}", currentState));
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     protected float timeEnteredState;
 | |
| 
 | |
|     public class State
 | |
|     {
 | |
|         public Action DoUpdate = DoNothing;
 | |
|         public Action DoFixedUpdate = DoNothing;
 | |
|         public Action DoLateUpdate = DoNothing;
 | |
|         public Action DoManualUpdate = DoNothing;
 | |
|         public Action enterState = DoNothing;
 | |
|         public Action exitState = DoNothing;
 | |
| 
 | |
|         public Enum currentState;
 | |
|     }
 | |
| 
 | |
|     public State state = new State();
 | |
| 
 | |
|     public Enum currentState
 | |
|     {
 | |
|         get
 | |
|         {
 | |
|             return state.currentState;
 | |
|         }
 | |
|         set
 | |
|         {
 | |
| 			if(state.currentState == value)
 | |
| 			{
 | |
| 				return;
 | |
| 			}
 | |
| 
 | |
|             ChangingState();
 | |
|             state.currentState = value;
 | |
|             ConfigureCurrentState();
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     [HideInInspector]
 | |
|     public Enum lastState;
 | |
| 
 | |
|     void ChangingState()
 | |
|     {
 | |
|         lastState = state.currentState;
 | |
|         timeEnteredState = Time.time;
 | |
|     }
 | |
| 
 | |
|     void ConfigureCurrentState()
 | |
|     {
 | |
|         if (state.exitState != null)
 | |
|         {
 | |
|             state.exitState();
 | |
|         }
 | |
| 
 | |
|         //Now we need to configure all of the methods
 | |
|         state.DoUpdate = ConfigureDelegate<Action>("Update", DoNothing);
 | |
|         state.DoFixedUpdate = ConfigureDelegate<Action>("FixedUpdate", DoNothing);
 | |
|         state.DoLateUpdate = ConfigureDelegate<Action>("LateUpdate", DoNothing);
 | |
|         state.DoManualUpdate = ConfigureDelegate<Action>("ManualUpdate", DoNothing);
 | |
|         state.enterState = ConfigureDelegate<Action>("EnterState", DoNothing);
 | |
|         state.exitState = ConfigureDelegate<Action>("ExitState", DoNothing);
 | |
| 
 | |
|         if (state.enterState != null)
 | |
|         {
 | |
|             state.enterState();
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     Dictionary<Enum, Dictionary<string, Delegate>> _cache = new Dictionary<Enum, Dictionary<string, Delegate>>();
 | |
| 
 | |
|     T ConfigureDelegate<T>(string methodRoot, T Default) where T : class
 | |
|     {
 | |
| 
 | |
|         Dictionary<string, Delegate> lookup;
 | |
|         if(!_cache.TryGetValue(state.currentState, out lookup))
 | |
|         {
 | |
|             _cache[state.currentState] = lookup = new Dictionary<string, Delegate>();
 | |
|         }
 | |
|         Delegate returnValue;
 | |
|         if (!lookup.TryGetValue(methodRoot, out returnValue))
 | |
|         {
 | |
|             var mtd = GetType().GetMethod(state.currentState.ToString() + "_" + methodRoot, System.Reflection.BindingFlags.Instance
 | |
|                 | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.InvokeMethod);
 | |
| 
 | |
|             if(mtd != null)
 | |
|             {
 | |
|                 returnValue = Delegate.CreateDelegate(typeof(T), this, mtd);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 returnValue = Default as Delegate;
 | |
|             }
 | |
|             lookup[methodRoot] = returnValue;
 | |
|         }
 | |
|         return returnValue as T;
 | |
| 
 | |
|     }
 | |
| 
 | |
|     void Update()
 | |
|     {
 | |
|         EarlyGlobalSuperUpdate();
 | |
| 
 | |
|         state.DoUpdate();
 | |
| 
 | |
|         LateGlobalSuperUpdate();
 | |
|     }
 | |
| 
 | |
|     void FixedUpdate()
 | |
|     {
 | |
|         state.DoFixedUpdate();
 | |
|     }
 | |
| 
 | |
|     void LateUpdate()
 | |
|     {
 | |
|         state.DoLateUpdate();
 | |
|     }
 | |
| 
 | |
|     protected virtual void EarlyGlobalSuperUpdate() { }
 | |
| 
 | |
|     protected virtual void LateGlobalSuperUpdate() { }
 | |
| 
 | |
|     static void DoNothing() { }
 | |
| } |