40 lines
1.1 KiB
GDScript
40 lines
1.1 KiB
GDScript
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)
|