############################################################################################################################ state.gd ######## @icon("res://_icons/state_icon.svg") class_name State extends Node #decide whether the current state is active or not var active: bool = false #reference to the state machine var state_machine: StateMachine = null #reference the character you want to control var controller: Worker @export_node_path("Worker") var controller_path: NodePath #called when state is first initialized. func initialize() -> void: #register itself its state machine state_machine = get_parent() #register the character node controller = get_node(controller_path) #called when state is entered func enter() -> void: active = true #called when state has exited func exit() -> void: active = false #called every frame this state is active func update(_delta: float) -> void: pass #called every physics fame this state is active func physics_update(_delta: float) -> void: pass #called when the controller has completed navigation func nav_completed() -> void: pass ############################################################################################################################ statemachine.gd ############### @icon("res://_icons/statemachine_icon.svg") class_name StateMachine extends Node #set the initial state the machine starts with @export var initial_state: State #the current running state of the machine var current_state: State #the registered states the machine knows about var states: Dictionary = {} func _ready() -> void: #wait for the nav mesh server to be initialized await NavigationServer2D.map_changed #initialize all the children states for child in get_children(): if child is State: states[child.name.to_lower()] = child child.initialize() #set the initial state if initial_state != null: change_state(initial_state.name) #called when transition from one state to the other has to be made func change_state(state_name: String) -> void: var new_state = states.get(state_name.to_lower()) #safety fallback if new_state == null: return #nothing to do if state stays the same if new_state == current_state: return #exit the current state if current_state != null: current_state.exit() current_state = new_state #enter the new state new_state.enter() #run the process function for the current state func _process(delta: float) -> void: if current_state != null: current_state.update(delta) #run the physics process function for the current state func _physics_process(delta: float) -> void: if current_state != null: current_state.physics_update(delta) func _on_navigation_agent_2d_navigation_finished() -> void: if current_state != null: current_state.nav_completed()
or share this direct link: