Course contentsShow
← Unreal Engine Game Development
Lesson 448 of 8806. AI, Navigation, and Decision MakingFree lesson

Building a Hierarchical State Machine Pattern

Extend your state machine to support nested states, allowing for modular logic like a combat state containing sub-states for attacking or dodging.

In this lesson, you will learn how to architect a Hierarchical State Machine (HSM) by nesting sub-states within parent states to handle complex behaviors like modular combat logic.

The Concept of Nesting

A standard Finite State Machine (FSM) becomes unwieldy when you have "Combat" logic that includes attacking, dodging, and blocking. Instead of creating a flat list of states (e.g., State_Combat_Attack, State_Combat_Dodge), we use a hierarchy. The Parent State handles general logic applicable to all sub-states, while the Active Sub-State handles the granular behavior.

Implementing the Hierarchy

Think of the Parent State as a "Container." When your AI enters State_Combat, it is effectively "in" that state, but it then delegates execution to a sub-state.

In your C++ state machine, you can represent this by giving your state base class a pointer to a ChildState.

// Inside your State base class
void UAIState::TickState(float DeltaTime) {
    if (ActiveSubState) {
        // Delegate logic to the specialized sub-state
        ActiveSubState->TickState(DeltaTime);
    } else {
        // Run general parent logic
        PerformGenericAction();
    }
}

Flow of Control

  1. Entry: When the AI enters State_Combat, it initializes State_Attack as the ActiveSubState.
  2. Execution: The state machine calls TickState on State_Combat. Because it has a sub-state, it forwards the call to State_Attack.
  3. Transition: If the AI needs to dodge, State_Combat simply swaps the ActiveSubState from State_Attack to State_Dodge. The parent state remains active, meaning you don't have to re-evaluate entry conditions for the combat "zone."

This approach reduces code duplication. For example, if you need a "Stunned" check that applies to all combat moves, you only write it once in the State_Combat parent, rather than duplicating it inside Attack, Dodge, and Block. By nesting logic, you keep your state machine clean, scalable, and easier to debug when your AI's decision tree grows beyond simple idle-to-chase transitions.

Key Takeaway: Use a hierarchical structure to delegate granular behavior to sub-states while maintaining shared logic and context within a single parent state.