diff --git a/StateMachine.cs b/StateMachine.cs
new file mode 100644
index 0000000..7748652
--- /dev/null
+++ b/StateMachine.cs
@@ -0,0 +1,134 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using ZelleGames.Log;
+
+namespace ZelleGames.StateMachine
+{
+ ///
+ /// Generic abstract state machine with OnEnter and OnExit features
+ ///
+ public abstract class StateMachine : MonoBehaviour
+ {
+ ///
+ /// Readonly State currently executing
+ ///
+ public State CurrentState { get; protected set; }
+
+ ///
+ /// Drive the current state if present
+ ///
+ private void Update()
+ {
+ if (CurrentState != null)
+ {
+ CurrentState.Update(Time.deltaTime);
+ }
+ }
+
+ ///
+ /// Drive the current state's FixedUpdate method if state is present
+ ///
+ private void FixedUpdate()
+ {
+ if (CurrentState != null)
+ {
+ CurrentState.FixedUpdate(Time.fixedDeltaTime);
+ }
+ }
+
+ ///
+ /// Public facing function to change state based on a transition.
+ /// Relies on an implementation of
+ ///
+ /// The transition to pass in. Validitiy depends on the implementation of GetNewState
+ public void TransitionState(Transition t)
+ {
+ var newState = GetNewState(t);
+ if (newState != null)
+ {
+ CurrentState?.OnExit();
+ CurrentState = newState;
+ CurrentState.StateMachine = this;
+ CurrentState.OnEnter();
+ } else
+ {
+ Logging.Log(LogLevel.WARN, $"Could not transition from {CurrentState} with {t}");
+ }
+ }
+
+ ///
+ /// Load a new state without consideration of the GetNewState function.
+ /// This is sessentially the "goto" of state machine management, use only if absolutely needed.
+ ///
+ ///
+ public void ForceState(State s)
+ {
+ CurrentState.OnExit();
+ CurrentState = s;
+ CurrentState.OnEnter();
+ }
+
+ ///
+ /// Derived classes should provide an implementation that returns a new depending
+ /// on the Transition passed in.
+ ///
+ ///
+ /// The new state for a valid transition for the current state,
+ /// Null otherwise to maintain current state
+ protected abstract State GetNewState(Transition t);
+ }
+
+ ///
+ /// Transitions are passed into the state machine to move from one state to the next.
+ ///
+ public abstract class Transition
+ {
+ ///
+ /// Generic object that can contain any information this transition needs to pass into the next state
+ ///
+ public object Context { get; }
+
+ public Transition() : this(null){}
+
+ public Transition(object ctx)
+ {
+ Context = ctx;
+ }
+ }
+
+ ///
+ /// Describes a finite state for a
+ /// in Unity.
+ ///
+ public abstract class State
+ {
+ ///
+ /// Reference to the parent statemachine. Derived classes can cast this reference into their specialized
+ /// class for specific statemachine functionality, or use this reference as is to operate on the base class
+ ///
+ public StateMachine StateMachine;
+
+ ///
+ /// Called every frame by the
+ ///
+ ///
+ public abstract void Update(float deltaTime);
+
+ ///
+ /// Called according to the Physics timing configuration by the
+ ///
+ ///
+ public virtual void FixedUpdate(float fixedDeltaTime) { }
+
+ ///
+ /// Called on the frame the machine switches to this state
+ ///
+ public virtual void OnEnter() { }
+
+ ///
+ /// Called on the last frame before this state is replaced.
+ ///
+ public virtual void OnExit() { }
+ }
+}
\ No newline at end of file