The StateMachine component is the main code entry point for a State Designer graph. Use its API when another script needs to control execution, inspect runtime state, respond to lifecycle changes, access Shared Variables, or save and restore the graph. If the behavior can be configured directly in the graph and Inspector, code is not required.
Watch the State Designer scripting tutorial on YouTube.
Start, stop, pause, or restart a graph
StartGraph()starts the graph and returns whether it started. Calling it on a paused graph resumes execution.StopGraph()stops the graph. Passtrueto itspauseparameter when the graph should be resumable.RestartGraph()stops and starts an active graph.Tick()requests one evaluation when the State Machine’s Update Mode is Manual. The evaluation occurs the next time the DOTS system group updates rather than immediately inside the call.
Use these methods for external controls such as enabling an agent, pausing gameplay, restarting a scenario, or advancing a turn-based simulation.
Query nodes and execution status
Read StateMachine.Status when UI or debugging code needs the status of the state connected to the Start node. It returns Inactive, Queued, Running, or Finished.
Use GetNode(Type) to find a logic node and GetEventNode(Type) to find an event node and its index. Both lookups can return a null node, so check the result before using it. After runtime Subgraph selection changes, ReevaluateSubgraphReferences() rebuilds the injected Subgraph content and restarts the graph.
Respond to lifecycle events
Subscribe to OnStateMachineStarted, OnStateMachineStopped, or OnStateMachineDestroyed when another system must react to graph execution. The save/load callbacks OnWillSave, OnDidSave, OnWillLoad, and OnDidLoad allow surrounding code to coordinate with persistence.
Read and update variables
GetVariable returns a Shared Variable by name. The overloads without a scope use Graph scope; the scoped overloads can request another supported SharedVariable.SharingScope. Prefer GetVariable<T> when the expected value type is known.
Use SetVariableValue<T> to update a value. Its return value reports whether the matching variable was found and set. Keep the name, type, and scope consistent with the variable configured in State Designer.
Save and restore a graph
Save writes one State Machine to a file and always includes Graph variables. Its variable-scope parameter can include additional scopes. Load accepts either a file path or existing SaveManager.SaveData; both overloads can run a callback after variables are restored.
API reference
The following signatures cover the StateMachine methods described on this page:
/// <summary>
/// Starts the state machine graph.
/// </summary>
/// <returns>True if the graph was started.</returns>
bool StartGraph()
/// <summary>
/// Returns the logic node of the specified type.
/// </summary>
/// <param name="type">The type of node to retrieve.</param>
/// <returns>The node of the specified type (can be null).</returns>
ILogicNode GetNode(Type type)
/// <summary>
/// Returns the event node of the specified type.
/// </summary>
/// <param name="type">The type of event node to retrieve.</param>
/// <returns>The event node and its index (node can be null).</returns>
(IEventNode, ushort) GetEventNode(Type type)
/// <summary>
/// Ticks the state machine. UpdateMode must be Manual.
/// </summary>
void Tick()
/// <summary>
/// Reevaluates SubgraphReference nodes by calling EvaluateSubgraphs.
/// </summary>
void ReevaluateSubgraphReferences()
/// <summary>
/// Stops or pauses the state machine.
/// </summary>
/// <param name="pause">Should the graph be paused?</param>
/// <returns>True if the graph was stopped or paused.</returns>
bool StopGraph(bool pause = false)
/// <summary>
/// Restarts the state machine.
/// </summary>
/// <returns>True if the graph was restarted.</returns>
bool RestartGraph()
/// <summary>
/// Returns the SharedVariable with the specified name (Graph scope).
/// </summary>
SharedVariable GetVariable(PropertyName name)
/// <summary>
/// Returns the SharedVariable with the specified name and scope.
/// </summary>
SharedVariable GetVariable(PropertyName name, SharedVariable.SharingScope scope)
/// <summary>
/// Returns the typed SharedVariable with the specified name (Graph scope).
/// </summary>
SharedVariable<T> GetVariable<T>(PropertyName name)
/// <summary>
/// Returns the typed SharedVariable with the specified name and scope.
/// </summary>
SharedVariable<T> GetVariable<T>(PropertyName name, SharedVariable.SharingScope scope)
/// <summary>
/// Sets a SharedVariable value (Graph scope).
/// </summary>
bool SetVariableValue<T>(PropertyName name, T value)
/// <summary>
/// Sets a SharedVariable value with explicit scope.
/// </summary>
bool SetVariableValue<T>(PropertyName name, T value, SharedVariable.SharingScope scope)
/// <summary>
/// Saves the state machine to the specified file path.
/// </summary>
/// <param name="filePath">Destination file path.</param>
/// <param name="variableSaveScope">Which variable scopes to save (Graph variables are always saved).</param>
/// <returns>True if save succeeded.</returns>
bool Save(string filePath, SaveManager.VariableSaveScope variableSaveScope = 0)
/// <summary>
/// Loads the state machine from a file path.
/// </summary>
/// <param name="filePath">Source file path.</param>
/// <param name="afterVariablesRestored">Optional callback after variable restore.</param>
/// <returns>True if load succeeded.</returns>
bool Load(string filePath, Action<StateMachine> afterVariablesRestored = null)
/// <summary>
/// Loads the state machine from SaveData.
/// </summary>
/// <param name="saveData">In-memory save data.</param>
/// <param name="afterVariablesRestored">Optional callback after variable restore.</param>
/// <returns>True if load succeeded.</returns>
bool Load(SaveManager.SaveData saveData, Action<StateMachine> afterVariablesRestored = null)
Manual update mode
When Update Mode is Manual, the graph does not request evaluation automatically each frame. Start it normally, then call Tick() whenever the simulation should advance:
using Opsive.StateDesigner.Runtime;
using UnityEngine;
public class ManualTickExample : MonoBehaviour
{
[SerializeField] private StateMachine m_StateMachine;
private void Start()
{
m_StateMachine.StartGraph();
}
public void AdvanceTurn()
{
m_StateMachine.Tick();
}
}
This pattern is useful for turn-based or deterministic step-driven simulations. A tick is queued for the next DOTS system-group update rather than completed during the Tick() call.
Event callback names
Flow lifecycle:
OnStateMachineStarted
OnStateMachineStopped
OnStateMachineDestroyed
Save/load lifecycle:
OnWillSave
OnDidSave
OnWillLoad
OnDidLoad
The first group reports graph execution changes. The second group surrounds save and load operations and reports their outcomes through the callback signatures exposed by StateMachine.
Verify the integration
In Play Mode, verify only the parts your script uses:
- Call
StartGraph()and confirm that it returnstrueandStatusreflects the Start branch’s execution. - If using Manual Update Mode, confirm that the graph advances after each requested tick and does not evaluate automatically between ticks.
- Subscribe and unsubscribe from the selected lifecycle callback, then confirm it fires during the matching operation.
- Read a known Shared Variable, update it with the matching name, type, and scope, and confirm that
SetVariableValue<T>returnstrue. - If saving, change the graph state after
Save, callLoad, and confirm that the saved state and variables return.
Check null node or variable lookups before use. A failed start, stop, variable update, save, or load is reported by its bool return value.