State Machine Framework
Last updated
Last updated
State Machines are a fundamental pattern for representing an event-driven system. We are surrounded by event-driven systems. Understanding the elegant simplicity of using a State Machine to design event-driven systems is useful for anyone designing interactive media.
The following link to the Unity Manual gives an overview of how State Machines are used in Unity. State Machines in Unity
Unity’s Animation State Machines provide a way to overview all of the animation clips related to a particular character and allow various events in the game (for example user input) to trigger different animations.
A Finite State Machine is model of a dynamic, event driven system. FSM's allow for simplification of the logic of a complex-dynamic event driven system. The simplification comes from the structure of the FSM, it specifies that the system can be represented by:
a finite set of states
a finite set of events that cause the system to change state
a well-defined set of state-event transitions
identification of the starting state
memory to keep track of the current state of the system.
no memory for tracking history of previous states
the system is always in one and only one state at any given time
events can be considered as being instantaneous
events are often considered as externally generated signals of the system.
State-Event-transitions specify which events cause allowable transitions between states. This information is often represented in a state-transition table with the following information: currentState, event, nextState
The State Machine structure insures that for each state that the system can be in, when the system is in that state, if a valid transition event occurs the system's state changes to the corresponding valid state.
This structure implies that there is no 'history' of prior states of the system. At any point in time, the system is in one specific state, and for that state, there are a well-defined set of events that can change the state. Events are often considered as external signals to the system. Examples of events are user key or mouse input, or physics engine notification that a collision has occurred between gameObjects.
The StateManager class will manage the following functions fo the stateMachine, see code at the bottom of this page.
Have logic to specify the system's starting-state
Have a reference-type variable to keep track of the current activeState
Delegate responsibility for scene logic to the current activeState.
Manage and coordinate messaging and state-transition event synchronization.
The StateManager class will use the Singleton Design Pattern which will insure that only 1 instance: instanceRef
of this class will exist in our program. The StateManager class will inherit from MonoBehaviour, this means we can attach this script to an empty GameObject in the starting scene for our program. We'll use the Unity function: DontDestroyOnLoad(gameObject)
to insure this script component is not destroyed when transitioning between scenes.
We will use the StateManager object to keep track of the current activeState
. Finite State Machines require that we maintain a persistent reference to the currently activeState, so this is one responsibility of our StateManager class.
We will use the StateManager instance to delegate control of the Scene's logic to the current activeState object instance. To delegate control, we need to provide the current activeState instance with the ability to have code executed when the Unity Event Functions execute.
For each Unity event function that is useful for the activeState to execute, we'll need to provide the activeState a similar event hook. The interface: IStateBase specifies that every StateX class implelents the method: InitializeObjectRefs( ) which has the same function as Unity Start( ), it's executed once when a scene is first loaded.
The diagram below gives an overview of how we will implement a State Machine Framework for a Unity project.
The sequence diagram below shows the asynchronous nature of the relationship between Unity Scenes and our custom states, The StateManager provides a conduit for synchronization communication of event messages between Unity Scenes and our custom states.
The StateManager receives notification from the Unity engine when a new scene has been loaded, it uses this event OnLevelWasLoaded(int levelNumber)
to send the activeState message, by exectuing the activeState.InitializeObjectRefs( )
, so the current activeState can now initialize all object references to gameObjects in the corresponding scene.