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() { }
							 | 
						|||
| 
								 | 
							
								}
							 |