My Player scene has a StateMachine node governing its behavior, with Idle, Move, Fall nodes as children under StateMachine. Another node, FallDownPit, listens for a signal telling it the player has wandered into a pit, and tells StateMachine to run the player's Fall state. It does this by having StateMachine and Fall as @export variables, and calling StateMachine's change_state(state: State) method with Fall as a parameter:
# fall_down_pit.gd
extends Node
@export var state_machine: StateMachine
@export var fall_state: State
func _ready() -> void:
Global.fell_in_pit.connect(fall_down_pit)
func fall_down_pit(fall_velocity: Vector2):
fall_state.fall_velocity = fall_velocity
state_machine.change_state(fall_state)
I've dragged Player's StateMachine and Fall nodes into FallDownPit's export variables, but when I run the game, both state_machine and fall_state are null. If I don't assign fall_state and only assign state_machine, state_machine is populated at runtime.
Scene graph:
Player
FallDownPit (has @export reference to both StateMachine and Fall)
StateMachine
Fall
Is assigning a 'nephew' node to an 'uncle' node bad practice? Am I running into some initialization order problem? Is there a better pattern to follow when trying to change states with outside signals?