In this case you should construct state machines of nodes and for each state-machine node, its child nodes are state handling nodes.
You can choose to have the state nodes process 'inputs' of your choice (signals, user inputs if you want, direct invocation from some other node), and the state can take on (flexibly) several strategies:
1. if - conditionals for simple stuff
2. switch statements
3. response child nodes where each has a response function and perhaps you use the child node name it identify the 'input' reacted to.
A unifying concept in state-machines is to think of a state responding 'messages' as inputs
The choice of strategy is then a matter of implementation.
the basic API for a FSM can be:
extends Node
class_name StateMachine
var initial_state:String
var current_state:String
func prepare() -- sets current_state to initial state etc
func transition_to(state_name:String) -- changes state
func respond_to(m): -- invokes current_state.respond_to and stays in or alters state depending on what it returns. States usefully have on_enter and and on_exit functions
[valid states are the children of StateMachine]
extends Node
class_name State
func get_machine() -> Node: return get_parent()
func on_enter(): -- utility/debugging
func on_exit(): -- utility/debugging
func respond_to(m) -> String: -- your choice, if/match/or lookup child node and invoke its response function
the response function returns itself or null to stay in the same state or go to another one. State names should be used for de-coupling (don't reference nodes!)
if your states become complex enough then Response classes as children of the state are warranted
extends Node
class_name StateResponse
func get_state() -> Node: return get_parent()
func get_machine() -> Node: return get_state().get_machine()
-- call these from state\'s on enter/exit to clean up or prepare for use.
func on_state_enter():
func on_state_exit():
func respond_to(m) -> String: handle the one input, returning same state or another state name
Now you can elect to have your StateMachine and States or even the Response nodes maintain internal vars and state. Each lower level has access to its parent context in a systematic way.
The above are base class scripts and you can extend "script-name" from them to create the statemachine of your desire