Godot 4.3+ Hierachical State Machine

In this post I am assuming you have basic knowledge of how a State Machine Works

This is a Hierarchical Finite State Machine!

This means it is setup in the editor as custom nodes!

The State Class

In this state machine, each s…


This content originally appeared on DEV Community and was authored by Umbr4x

In this post I am assuming you have basic knowledge of how a State Machine Works

This is a Hierarchical Finite State Machine!

This means it is setup in the editor as custom nodes!

The State Class

In this state machine, each state will extend from the State class below. Transitions between states can be called with this nice function I made called transition_to(). When using this state machine treat the update and physics_update like _process and _physics_process respectively.

class_name State
extends Node

signal transitioned(state: State, new_state_name: String)

var player: CharacterBody2D
@onready var sprite: AnimatedSprite2D = %AnimatedSprite2D

func enter() -> void:
    pass

func exit() -> void:
    pass

func update(delta: float) -> void:
    pass

func physics_update(delta: float) -> void:
    pass

func transition_to(new_state_name: String) -> void:
    transitioned.emit(self, new_state_name)

The State Machine

The State Machine node is where we will be adding our State nodes to as children. The state machine mostly takes care of transitions, keeping track of current state, and executes the code of the states.
Must be a child of a CharacterBody2D (Aka your player)


class_name StateMachine
extends Node

@export var initial_state: State
var current_state: State
var states: Dictionary = {}

func _ready() -> void:
    _initialize_states()
    _set_initial_state()

func _initialize_states() -> void:
    for child in get_children():
        if child is State:
            states[child.name.to_lower()] = child
            child.transitioned.connect(_on_state_transition)

func _set_initial_state() -> void:
    if initial_state:
        _assign_player_reference(initial_state)
        initial_state.enter()
        current_state = initial_state
    else:
        push_warning("No initial state set for StateMachine in " + owner.name)

func _process(delta: float) -> void:
    if current_state:
        current_state.update(delta)

func _physics_process(delta: float) -> void:
    if current_state:
        current_state.physics_update(delta)

func _on_state_transition(state: State, new_state_name: String) -> void:
    if state != current_state:
        return

    var new_state = states.get(new_state_name.to_lower())
    if not new_state:
        push_warning("State '" + new_state_name + "' not found in StateMachine")
        return

    _transition_to_new_state(new_state)

func _transition_to_new_state(new_state: State) -> void:
    current_state.exit()
    current_state = new_state
    _assign_player_reference(new_state)
    new_state.enter()

func _assign_player_reference(state: State) -> void:
    var parent = get_parent()
    if parent is CharacterBody2D:
        state.player = parent
    else:
        push_warning("StateMachine's parent must be CharacterBody2D")

Example States and proper usage:

Write code necessary only for that state.


class_name IdleState
extends State

@export_range(120, 420) var friction: float


func enter() -> void:
    print("Entered Idle")
    sprite.play("idle")

func exit() -> void:
    print("Exited Idle")

func update(delta: float) -> void:
    if Input.get_axis("ui_left", "ui_right") != 0:
        transition_to("Walk")
    if not player.is_on_floor():
        transition_to("Fall")


func physics_update(delta: float) -> void:
    if player.velocity.x != 0:
        player.velocity.x = lerp(player.velocity.x, 0, friction * delta)


This content originally appeared on DEV Community and was authored by Umbr4x


Print Share Comment Cite Upload Translate Updates
APA

Umbr4x | Sciencx (2025-01-22T16:19:09+00:00) Godot 4.3+ Hierachical State Machine. Retrieved from https://www.scien.cx/2025/01/22/godot-4-3-hierachical-state-machine-2/

MLA
" » Godot 4.3+ Hierachical State Machine." Umbr4x | Sciencx - Wednesday January 22, 2025, https://www.scien.cx/2025/01/22/godot-4-3-hierachical-state-machine-2/
HARVARD
Umbr4x | Sciencx Wednesday January 22, 2025 » Godot 4.3+ Hierachical State Machine., viewed ,<https://www.scien.cx/2025/01/22/godot-4-3-hierachical-state-machine-2/>
VANCOUVER
Umbr4x | Sciencx - » Godot 4.3+ Hierachical State Machine. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/01/22/godot-4-3-hierachical-state-machine-2/
CHICAGO
" » Godot 4.3+ Hierachical State Machine." Umbr4x | Sciencx - Accessed . https://www.scien.cx/2025/01/22/godot-4-3-hierachical-state-machine-2/
IEEE
" » Godot 4.3+ Hierachical State Machine." Umbr4x | Sciencx [Online]. Available: https://www.scien.cx/2025/01/22/godot-4-3-hierachical-state-machine-2/. [Accessed: ]
rf:citation
» Godot 4.3+ Hierachical State Machine | Umbr4x | Sciencx | https://www.scien.cx/2025/01/22/godot-4-3-hierachical-state-machine-2/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.