Skip to content

Hybrid State Machines

Inspiaaa edited this page May 28, 2024 · 1 revision

What is the HybridStateMachine class?

UnityHFSM builds on three fundamental concepts: state machines, transitions, and states.

  • State machines manage states and transitions, as well as the timing mechanics of state changes. Because state machines inherit from the StateBase class, you can use them as regular states, allowing you to create hierarchies.
  • Transitions define the conditions under which a state change may occur.
  • States let you define custom logic which is run when the state enters / updates / exits, or when specific events are emitted (action system).

The HybridStateMachine class is a hybrid between a StateMachine and a State, essentially combining the best of both worlds. It acts like a regular state machine, meaning that you can add states and transitions. At the same time, it also lets you add callbacks for enter / update / exit events and custom actions, as if it were a "normal" state.

Regarding its implementation, it inherits from the StateMachine class and provides additional features that you are used to fromm the State class.

The HybridStateMachine class is most useful when it is used as a nested state machine, as it allows you to factor out common code from the sub-states, thus reducing duplicate code.

Usage

In the constructor, you can pass in callbacks that are similar to those passed into the State constructor. If any of these are not needed, they can simply be omitted.

var fsm = new HybridStateMachine(
    beforeOnEnter: self => {
        // Called before the OnEnter method of the start state when the parent
        // state machine switches to this state machine.
    },
    afterOnEnter: self => {
        // Called after the OnEnter method of the start state.
    },

    beforeOnLogic: self => {
        // Called on each OnLogic call before the OnLogic method 
        // of the active state.
    },
    afterOnLogic: self => {
        // Called after the OnLogic method of the active state.
    },

    beforeOnExit: self => {
        // Called before the OnExit method of the active state when the parent
        // state machine switches to another state, exiting this state machine.
    },
    afterOnExit: self => {
        // Called after the OnExit method of the active state.
    }
);

The HybridStateMachine class also allows you to define custom actions.

fsm.AddAction("OnGameOver", () => print("GameOver"));
fsm.AddAction<float>("OnHit", damage => print($"Damage: {damage}"));

You can also use a fluent interface to define these actions:

var fsm = new HybridStateMachine()
    .AddAction("OnGameOver", () => print("GameOver"))
    .AddAction<float>("OnHit", damage => print($"Damage: {damage}"));

Regarding the order of execution, the custom actions are called before propagating the action event further down the hierarchy:

var fsm = new HybridStateMachine()
    .AddAction("MyEvent", () => print("Hybrid State Machine"));

fsm.AddState("A", new State()
    .AddAction("MyEvent", () => print("State A")));

fsm.SetStartState("A");
fsm.Init();

fsm.OnAction("MyEvent");  // Prints "Hybrid State Machine" and then "State A".
Clone this wiki locally