class_name StateMachine extends Node @export var initial_state: State = null # use first child as 'active' state @onready var state: State = (func get_initial_state() -> State: return initial_state if initial_state != null else get_child(0) ).call() # Connect states on ready, then wait. func _ready() -> void: for node: State in find_children("*", "State"): node.finished.connect(_transition_to_next_state) await owner.ready state.enter("") # pass unhandled input to state. func _unhandled_input(event: InputEvent) -> void: state.handle_input(event) # Pass process tick to state. func _process(delta: float) -> void: state.update(delta) # Pass physics tick to state. func _physics_process(delta: float) -> void: state.physics_update(delta) # Transition to next state func _transition_to_next_state(target_path: String, data: Dictionary = {}) -> void: if not has_node(target_path): printerr(owner.name + ": Trying to transition to state " + target_path + ", which does not exist.") return var previous_state_path := state.name state.exit() state = get_node(target_path) state.enter(previous_state_path, data)