Null instance error when setting global player position from save screen

Godot Version

4.6.1 Stable

Question

Hi everyone. So I’m working on a practice JRPG prototype and one of the things I wanted to do is create a ‘save room’ that the player saves in and then leaves.

What I have set up right now is a debug room which contains the Player node as a unique name, with the following script.

class_name Player extends CharacterBody3D

#region Variables
@onready var forward: RayCast3D = $Forward
@onready var right: RayCast3D = $Right
@onready var left: RayCast3D = $Left
const SPEED: float = 0.3
const ROTATE_SPEED: float = 0.4 
@onready var tween: Tween
#endregion

I then instantiated a separate control node scene, which is my save UI menu. Its just two buttons, right now, one for saving and exiting, with the following script:

extends Control

@onready var player: Player = %Player
@onready var save: Button = $Options/Save
@onready var exit: Button = $Options/Exit
@onready var spawn_point: Marker3D = %SpawnPoint


const SAVE_PATH = "user://savegame.data"
@warning_ignore("untyped_declaration")

func _ready() -> void:
	player = get_tree().get_first_node_in_group("Player")

func _on_options_button_pressed(button: BaseButton, index: int) -> void:
	match button.text:
		"SAVE":
			@warning_ignore("untyped_declaration")
			var file =  FileAccess.open(SAVE_PATH, FileAccess.WRITE)
			@warning_ignore("untyped_declaration")
			var saved_data = {}
		  
			saved_data["player_global_position"] = player.global_position

			file.store_var(saved_data)
			file.close()
		
		"EXIT":
			TransitionLayer.change_level("res://src/dungeons/debug_room/debug_room.tscn")
			player.global_position = spawn_point.global_position
		_:
			pass

I want to have it so that the player’s position on pressing the ‘exit’ button places them at a Marker3D location. Of course the issue is, since these are two separate scenes, I receive the following error:

“Invalid access to property or key ‘global_position’ on a base object of type ‘null instance’.”

I assume the issue is, the ‘player’ is a null instance since it doesn’t exist in the save screen. So my question is, what should I be doing instead to make this work? Simply copying in the Player node into the save screen does not work.

Thank you.

Are you sure the problem is the player variable and not spawn_point?

Unique node names can only be used within the same scene. If your control node is part of a different scene, you can’t access the player nor the spawn point this way. For player this shouldn’t matter (because you are setting it to get_tree().get_first_node_in_group("Player") in _ready()), but spawn_point would still be null.


The easiest way to access these nodes is probably to @export both variables:

@export var player: Player
@export var spawn_point: Marker3D

and set them in the Inspector in the debug room scene.