Skip to content

Instantly share code, notes, and snippets.

@RainCatalyst
Last active August 31, 2022 17:52
Show Gist options
  • Save RainCatalyst/3cdedbef81a918bcd8f6a5c1be936659 to your computer and use it in GitHub Desktop.
Save RainCatalyst/3cdedbef81a918bcd8f6a5c1be936659 to your computer and use it in GitHub Desktop.
Simple state machine in Godot
## State machine usage example
## Add states as children to the States node
extends Node
# Setup fsm
onready var fsm = StateMachine.new(self, $States, $States/menu, true)
func _process(delta):
# Update fsm
fsm.process(delta)
# Change state on press
if Input.is_action_just_pressed("ui_accept"):
fsm.next_state = fsm.states.settings
## State class for the StateMachine
## Since it extends node, you can also use _ready and connect signals if needed
class_name State extends Node
var fsm
var object: Node
func setup(_fsm, _object: Node):
fsm = _fsm
object = _object
func enter(from_state: State):
pass
func exit(to_state: State):
pass
func process(delta):
pass
## Finite state machine
class_name StateMachine extends Object
var object: Node
var states := {}
var previous_state: State
var next_state: State
var current_state: State
var debug: bool
func _init(_object, _state_holder: Node, _initial_state: State, _debug: bool = false):
object = _object
debug = _debug
setup_states(_initial_state, _state_holder)
func setup_states(initial_state: State, state_holder: Node):
for state in state_holder.get_children():
states[state.name] = state
state.setup(self, object)
next_state = initial_state
func process(delta):
if next_state != current_state:
if current_state != null:
current_state.exit(next_state)
if debug:
print('Exited %s' % current_state.name)
previous_state = current_state
current_state = next_state
current_state.enter(previous_state)
if debug:
print('Entered %s' % current_state.name)
current_state.process(delta)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment