Godot Version
v4.6.1
Question
Hello all, I’ve been following this tutorial by StayAtHomeDev (https://www.youtube.com/watch?v=L5ObCs9OMRY). I’ve got to roughly the 26 minute mark and run into issues with the StateChart node and some associated scripts.
The relevant bits of my node structure are
PlayerController (player_controller.gd)
|> (Mesh, Collision, Cameras etc)
|v StateChart (https://godotengine.org/asset-library/asset/1778)
|> Idle (atomic (single) state, sends a signal)
|> OnMoving (transition to Moving on event "onMoving")
|> Moving (atomic state)
(generic nodes)
|v StateMachine (state_machine.gd)
|v MovementState (base_state.gd)
|v GroundedState
|v IdleState (idle_state.gd)
Essentially I’m trying to reference a Vector2 value defined in player_controller.gd from the child node IdleState. This lets idle_state.gd send an event to the transition node OnMoving, which will update the state chart to say the player is moving, and this will let me do more logic that’ll come later in the tutorial. My root node handles basic movement stuff and is supposed to pass values down to the child nodes.
player_controller.gd:
class_name PlayerController extends CharacterBody3D
var _input_dir : Vector2 = Vector2.ZERO
func _physics_process(delta: float) -> void:
# (Apply gravity, handle jump)
# get WASD input vector
var _input_dir := Input.get_vector("player_strafe_left", "player_strafe_right", "player_forward", "player_backward")
# (lerp velocity, apply new velocity)
move_and_slide()
state_machine.gd:
class_name PlayerStateMachine extends Node
@export var player_controller : PlayerController
base_state.gd defines PlayerState and gives player_controller to idle_state.gd later:
class_name PlayerState extends Node
var player_controller : PlayerController
func _ready() -> void:
if %StateMachine and %StateMachine is PlayerStateMachine:
player_controller = %StateMachine.player_controller
idle_state.gd:
extends PlayerState
var input_len : float = 0.0
func _on_idle_state_processing(delta: float) -> void:
if player_controller.is_node_ready():
var input_len = player_controller._input_dir.length()
if (player_controller and (input_len > 0)):
player_controller.state_chart.send_event("onMoving")
_on_idle_state_processing() is the signal from the Idle single state node and it calls every frame. Trouble is player_controller._input_dir.length() is always 0.0 in this scope, like a default value but not null, when it should be greater than 0 since its the WASD input (not normalised). Is there a better way to reference variables in a parent node or root node that I’m missing? Massive Godot noob here, still learning and hope my issue isn’t too badly worded.