AutoLoad Breaking my player

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Kalelojed_YT

-tree
Player(KinematicBody, script Autoloaded)
MeshInstance
CollisionShape
Head(Spatial Node)
Camera

One thing that has been frustrating me for too long is that i made a simple player script but then, when I Autoloaded the script to be able to access the vars from my spaceship, it said that my head node didn’t exist, i tried removing the head rotation code but the same error just went to the camera var. Does anyone know how to fix this.

script:
onready var head = $Head
onready var camera = $Head/Camera

func _ready():
#hides the cursor
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)

func _input(event):

if event is InputEventMouseMotion:
	rotate_y(deg2rad(-event.relative.x * mouse_sense))
	head.rotate_x(deg2rad(-event.relative.y * mouse_sense)) <--- null instance error
	head.rotation.x = clamp(head.rotation.x, deg2rad(-90), deg2rad(90))

Thank you.
–Kalelojed–

:bust_in_silhouette: Reply From: Lopy

When you set a script as an Autoload, you tell Godot to create an instance of it when the game starts, that should persist through scene changes, and is a direct child of the “root” node in the SceneTree. Your error messages come from that second instance.

To better see what is happening, start your game, then focus the Editor without closing the game, and just above the tree view on your left, select “Remote”. This will show you the tree of your game as it is running. You can also call $"/root".print_tree_pretty() (inside some Node’s _ready()) for a textual representation.


To access your Player Node from your spaceships, you can use:

  • Direct tree walking, with $Path/to/player, or get_node(“Path/to/player”).
  • Indirect tree walking, with find_node(“player”) or find_parent(“player”). Can be “slow”, if your tree is big. You can avoid doing it repeatedly by keeping the value in a variable.
  • Use Areas, Raycasts, or other physics Nodes, to not only detect the Player being in a position, but also retrieve it’s Node.
  • Use an Autoload to hold the information. The Autoload has a var player, and the Player sets the Autoloads variable to itself (MyAutoload.player = self). While this is practical, it can cause issues when you change scenes (the player is likely deleted, so the variable’s content is corrupt, see is_instance_valid()), or if you decide to have multiple Players (unlikely for a player). The general issues with singletons apply, even if Godot’s Autoloads aren’t perfect singletons.