create abstract state machine class

This commit is contained in:
yuki 2025-11-14 15:53:20 -03:00
parent 594605fe70
commit 13ae274106
3 changed files with 55 additions and 0 deletions

View file

@ -0,0 +1,48 @@
## Virtual base class for all nodes that deal directly with states.
## Extend this class and override its methods to implement a state machine.
@abstract class_name StateMachine extends Node
## The initial state of the state machine. If not set, the first child node is used.
@export var initial_state: State
## The state machine's current loaded state
@onready var state: State = _get_initial_state()
func _ready() -> void:
for state_node: State in find_children("*", "State"):
state_node.finished.connect(_transition_to_next_state)
await owner.ready
state.enter("")
func _unhandled_input(event: InputEvent) -> void:
state.handle_input(event)
func _process(delta: float) -> void:
state.update(delta)
func _physics_process(delta: float) -> void:
state.physics_update(delta)
## Called when initial state is not specified.
## Returns the first child node by default.
## Override if necessary, but don't call it directly.
func _get_initial_state() -> State:
return initial_state if initial_state != null else get_child(0)
## Transitions the active state out after receiving a finished signal.
func _transition_to_next_state(target_state_path: String, data: Dictionary = {}) -> void:
if not has_node(target_state_path):
printerr(owner.name + ": Trying to transition to state " + target_state_path + " but it does not exist.")
return
var previous_state_path: StringName = state.name
state.exit()
state = get_node(target_state_path)
state.enter(previous_state_path, data)

View file

@ -0,0 +1 @@
uid://dqjaxgmyxq3rx

View file

@ -0,0 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://cy4h0xcy2kscg"]
[ext_resource type="Script" uid="uid://dqjaxgmyxq3rx" path="res://scenes/classes/state_machine.gd" id="1_rnohx"]
[node name="StateMachine" type="Node"]
script = ExtResource("1_rnohx")