Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # ---- StateMachine.gd ----
- class_name StateMachine
- extends Node
- enum Step {
- ENTER,
- UPDATE,
- EXIT,
- }
- var states : Array
- var current_state : int
- var current_update_func : FuncRef
- var next_state : int
- var empty_state : FuncRef = funcref(self, "empty")
- func add(
- instance : Object,
- state_name : int,
- enter_function : String = "empty",
- update_function : String = "empty",
- exit_function : String = "empty"
- ) -> void:
- states.insert(state_name, [
- _get_funcref(instance, enter_function),
- _get_funcref(instance, update_function),
- _get_funcref(instance, exit_function)
- ])
- func start(state : int) -> void:
- current_state = state
- next_state = current_state
- current_update_func = states[current_state][Step.UPDATE] # Set UPDATE function
- states[state][Step.ENTER].call_func() # Run ENTER function
- func update(delta : float) -> void:
- current_update_func.call_func(delta) # Run UPDATE function
- if next_state != current_state:
- states[current_state][Step.EXIT].call_func()
- states[next_state][Step.ENTER].call_func()
- current_state = next_state
- current_update_func = states[current_state][Step.UPDATE]
- current_update_func.call_func(delta) # Run UPDATE function
- func change_state(state : int) -> void:
- next_state = state
- # Default empty function
- func empty() -> void:
- pass
- func _get_funcref(instance : Object, func_name : String = "empty") -> FuncRef:
- if func_name == "empty":
- return empty_state
- return funcref(instance, func_name)
- # ---- How I'm using it on my player node ----
- var fsm : StateMachine
- enum State {
- GROUNDED,
- JUMPING,
- FALLING,
- }
- func _ready():
- # Set up State Machine
- fsm = StateMachine.new()
- fsm.set_name("StateMachine")
- add_child(fsm)
- # Set up States
- fsm.add(self, State.GROUNDED,
- "st_grounded_enter",
- "st_grounded_update",
- "st_grounded_exit")
- fsm.add(self, State.JUMPING,
- "st_jumping_enter",
- "st_jumping_update",
- "st_jumping_exit")
- fsm.add(self, State.FALLING,
- "st_falling_enter",
- "st_falling_update",
- "st_falling_exit")
- fsm.start(State.FALLING)
- func _physics_process(delta: float) -> void:
- fsm.update(delta)
- # Then, below all that, I make functions for all the enter/update/exit states I set up above
- # with the update states taking a (delta: float) argument
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement