State.gd
@abstract class_name State
extends Node
enum Name { IDLE, GROW, END }
var actor: Actor
var state_name: Name
func enter() -> void:
# logic on enter
pass
func exit() -> void:
# logic on exit
pass
@abstract func setup(actor : Actor) -> void
@abstract func process_physics_frame(delta: float) -> Name
states/IdleState.gd
extends State
class_name IdleState
func enter() -> void:
# on enter logic
pass
func exit() -> void:
pass
func setup(actor : Actor) -> void:
self.actor = actor
self.state_name = State.Name.IDLE
func process_physics_frame(delta : float) -> State.Name:
# logic
StateMachine.gd
extends Node
class_name StateMachine
@export var actor : Actor
@export var starting_state : State
@export var state_dictionary : Dictionary[State.Name, State]
var current_state : State
func setup() -> void:
for key: State.Name in state_dictionary:
state_dictionary[key].setup(self.actor)
change_state(starting_state)
func change_state(new_state: State) -> void:
if current_state:
current_state.exit()
current_state = new_state
current_state.enter()
func process_physics_frame(delta: float) -> void:
var new_state: State = state_dictionary[current_state.process_physics_frame(delta)]
if new_state != current_state:
change_state(new_state)
actor.move_and_slide()