SHARE
TWEET

Unity string based state machine

a guest Oct 22nd, 2014 172 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4.  
  5. public class StateTester : MonoBehaviour {
  6.  
  7.         protected virtual void Start(){
  8.                 InitStateSystem();
  9.         }
  10.  
  11.         protected virtual void Update(){
  12.                 _activeState.Update();
  13.         }
  14.  
  15.         #region State machine
  16.  
  17.         Dictionary<string, State> states; //we use this to link states to strings
  18.         public string activeState {
  19.                 get; //other scripts can read our state string
  20.                 private set; //but not change it (which is what SetState() is for)
  21.                 //you could change this to set { SetState(value); } but I prefer not to
  22.         }
  23.         State _activeState;
  24.        
  25.         public const string STATE_A = "State A"; //we use constants for this largely to simply code
  26.         public const string STATE_B = "State B"; //if we use the constants to set/change states, we don't have to worry about typos
  27.  
  28.         //this fills our dictionary, linking the strings to the local state class instances
  29.         protected virtual void InitStateSystem(){
  30.                 //populate the dictionary with all our states
  31.                 states = new Dictionary<string, State>();
  32.                 states.Add(STATE_A, stateA);
  33.                 states.Add(STATE_B, stateB);
  34.  
  35.                 //initialise our states
  36.                 stateA.Init(this);
  37.                 stateB.Init(this);
  38.  
  39.                 //set initial state
  40.                 _activeState = stateA;
  41.                 activeState = STATE_A;
  42.         }
  43.  
  44.         public virtual void SetState(string nextState){
  45.                 if(activeState == nextState) return; //abort if the state we're changing to is the same one we're running anyway
  46.  
  47.                 State s;
  48.                 //try to find the string nextState in the dictionary, which also sets s if we find one
  49.                 if(!states.TryGetValue(nextState, out s)){
  50.                         //we could not find a state with that string in the dictionary, so early out without changing anything
  51.                         Debug.LogError("Unsupported state " + nextState + "!");
  52.                         return;
  53.                 }
  54.  
  55.                 s.StartState();
  56.                 _activeState = s;
  57.                 activeState = nextState;
  58.         }
  59.  
  60.         //this is the abstracted form of a state class
  61.         public abstract class State {
  62.                 //common state parameters here
  63.                 protected StateTester owner; //this is what the state is controlling
  64.  
  65.                 //add links to properties in the owner we want to easily read / edit, for example our Transform
  66.                 protected Transform transform { get { return owner.transform; } }
  67.  
  68.                 //essentially the State's 'Start' function, but you have to call this manually
  69.                 public virtual void Init(StateTester a){
  70.                         owner = a;
  71.                 }
  72.  
  73.                 //or whatever function every state is expected to have and be used for
  74.                 public abstract void Update();
  75.  
  76.                 public abstract void StartState();
  77.  
  78.         }
  79.  
  80.         #endregion
  81.  
  82.         #region State A
  83.        
  84.         //this is our local instance of StateA, which will show up in the inspector
  85.         public StateA stateA;
  86.  
  87.         [System.Serializable] //this tells Unity to save instances of this class
  88.         public class StateA : State {
  89.  
  90.                 //properties unique to State A here
  91.                 public float spinSpeed = 3;
  92.  
  93.                 public override void StartState () {
  94.                         Debug.Log("I'm state A! See me spin!");
  95.                 }
  96.  
  97.                 public override void Update () {
  98.                         transform.Rotate(0, Time.deltaTime * spinSpeed, 0);
  99.                 }
  100.  
  101.         }
  102.  
  103.         #endregion
  104.  
  105.         #region State B
  106.  
  107.         //this is our local instance of StateB, which will show up in the inspector
  108.         public StateB stateB;
  109.  
  110.         [System.Serializable] //this tells Unity to save instances of this class
  111.         public class StateB : State {
  112.                
  113.                 //properties unique to State B here
  114.                 public float flySpeed = 4;
  115.                
  116.                 public override void StartState () {
  117.                         Debug.Log("I'm state B! TO THE MOOOOON!");
  118.                 }
  119.                
  120.                 public override void Update () {
  121.                         transform.Translate(0, Time.deltaTime * flySpeed, 0);
  122.                 }
  123.         }
  124.  
  125.         #endregion
  126. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top