diff --git a/scripts/state_machine.gd b/scripts/state_machine.gd new file mode 100644 index 0000000..cd81939 --- /dev/null +++ b/scripts/state_machine.gd @@ -0,0 +1,45 @@ +extends Node + +@export var initial_state : State + +var states : Dictionary = {} +var current_state : State = null + +func _ready() -> void: + for child in get_children(): + if child is State: + states[child.name.to_lower()] = child + child.Transitioned.connect(_on_state_transitioned) + if initial_state: + initial_state.enter() + current_state = initial_state + +func _process(delta: float) -> void: + if current_state: + current_state.frame_update(delta) + +func _physics_process(delta: float) -> void: + if current_state: + current_state.physics_update(delta) + +func _on_state_transitioned(state: State, new_state_name: String) -> void: + if state != current_state: + push_warning("Attempting transition from nonactive state!") + return + change_state(new_state_name) + +func change_state(new_state_name: String) -> void: + var key := new_state_name.to_lower() + var new_state: State = states.get(key) + + if new_state == null: + push_error("New state not found: %s" % key) + return + elif current_state == new_state: + push_warning("Already in state: %s" % key) + return + + if current_state: + current_state.exit() + new_state.enter() + current_state = new_state