Advertisement
davemakes

godot fsm

Jul 1st, 2022 (edited)
373
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.33 KB | None | 0 0
  1. # ---- StateMachine.gd ----
  2.  
  3. class_name StateMachine
  4. extends Node
  5.  
  6. enum Step {
  7. ENTER,
  8. UPDATE,
  9. EXIT,
  10. }
  11.  
  12. var states : Array
  13. var current_state : int
  14. var current_update_func : FuncRef
  15. var next_state : int
  16. var empty_state : FuncRef = funcref(self, "empty")
  17.  
  18.  
  19. func add(
  20. instance : Object,
  21. state_name : int,
  22. enter_function : String = "empty",
  23. update_function : String = "empty",
  24. exit_function : String = "empty"
  25. ) -> void:
  26. states.insert(state_name, [
  27. _get_funcref(instance, enter_function),
  28. _get_funcref(instance, update_function),
  29. _get_funcref(instance, exit_function)
  30. ])
  31.  
  32.  
  33. func start(state : int) -> void:
  34. current_state = state
  35. next_state = current_state
  36. current_update_func = states[current_state][Step.UPDATE] # Set UPDATE function
  37. states[state][Step.ENTER].call_func() # Run ENTER function
  38.  
  39.  
  40. func update(delta : float) -> void:
  41. current_update_func.call_func(delta) # Run UPDATE function
  42.  
  43. if next_state != current_state:
  44. states[current_state][Step.EXIT].call_func()
  45. states[next_state][Step.ENTER].call_func()
  46. current_state = next_state
  47. current_update_func = states[current_state][Step.UPDATE]
  48. current_update_func.call_func(delta) # Run UPDATE function
  49.  
  50.  
  51. func change_state(state : int) -> void:
  52. next_state = state
  53.  
  54.  
  55. # Default empty function
  56. func empty() -> void:
  57. pass
  58.  
  59.  
  60. func _get_funcref(instance : Object, func_name : String = "empty") -> FuncRef:
  61. if func_name == "empty":
  62. return empty_state
  63.  
  64. return funcref(instance, func_name)
  65.  
  66.  
  67.  
  68.  
  69. # ---- How I'm using it on my player node ----
  70.  
  71. var fsm : StateMachine
  72.  
  73. enum State {
  74. GROUNDED,
  75. JUMPING,
  76. FALLING,
  77. }
  78.  
  79. func _ready():
  80. # Set up State Machine
  81. fsm = StateMachine.new()
  82. fsm.set_name("StateMachine")
  83. add_child(fsm)
  84.  
  85. # Set up States
  86. fsm.add(self, State.GROUNDED,
  87. "st_grounded_enter",
  88. "st_grounded_update",
  89. "st_grounded_exit")
  90. fsm.add(self, State.JUMPING,
  91. "st_jumping_enter",
  92. "st_jumping_update",
  93. "st_jumping_exit")
  94. fsm.add(self, State.FALLING,
  95. "st_falling_enter",
  96. "st_falling_update",
  97. "st_falling_exit")
  98. fsm.start(State.FALLING)
  99.  
  100. func _physics_process(delta: float) -> void:
  101. fsm.update(delta)
  102.  
  103. # Then, below all that, I make functions for all the enter/update/exit states I set up above
  104. # with the update states taking a (delta: float) argument
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement