get_tree().get_current_scene() is returning null

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

I was trying to get the name of the current scene by using get_tree().get_current_scene().get_name() but i’m getting the error:

Attempt to call function ‘get_name’ in base ‘null instance’ on a null
instance.

I found out that get_current_scene() was giving me null. This is after a change scene where the function was working as intended.
i.e.
get_tree().get_current_scene().get_name() in menu.gd returns menu
get_tree().get_current_scene().get_name() in game.gd returns the error because get_tree().get_current_scene() is null

levelManager.gd (autoloaded singleton) [full script]

extends Node

const SCENE_PATH = "res://scenes/"

func change_scene(scene_name):
	deffer_call("_deffered_change_scene", scene_name)

func _deffered_change_scene(scene_name):
	var path = SCENE_PATH + scene_name + ".tscn"
	var root = get_tree().get_root()
	var current = root.get_child(root.get_child_count() - 1)
	current.free()
	var scene_resource = ResourceLoader.load(path)
	var new_scene = scene_resource.instance()
	get_tree().get_root().add_child(new_scene)
	get_tree().set_current_scene(new_scene)
	
func _process(_delta):
	if Input.is_action_pressed("close"):
		get_tree().quit()
		
func deffer_call(func_name, func_param):
	call_deferred(func_name, func_param)

–[Shortened scripts:]–

menu.gd

extends Node

func _ready():
	var scene_name = get_tree().get_current_scene().get_name()
	print(scene_name) # returns 'menu'

# on full version of the script, mechanism that called _change_scene here

func _change_scene():
	levelManager.change_scene("game")

game.gd

extends Node

#game variables declared here

func _ready():
	var scene_name = get_tree().get_current_scene().get_name()
	print(scene_name) #returns an error due to get_tree().get_current_scene() being null

# rest of the game logic code here

I want to know why this is the case. Is there something wrong with the way i changed scenes from levelManager.gd?

I resolved this issue by:
setting var current_scene_name in levelManager.gd
– both in menu.gd and game.gd
re-setting current_scene_name by calling self.get_name()

i.e.
levelManager.gd

var current_scene_name

menu.gd and game.gd

var scene_name = self.get_name()
levelManager.current_scene_name(scene_name)

^ This is obviously a workaround. It works but i still want to know why i’m getting different outputs after calling get_tree() while they practically are in the same remote location in the node.

link to screenshot because embedding images doesn’t seem to work:
treeScreenshotBeforeAndAfterChangingScenes

This is probably a duplicate of this but this isn’t exactly an answer and i’m not entirely sure it can be a comment there either.

Just BTW. This is much easier to do with get_tree().get_current_scene().get_filename(). This returns the path in the filesystem to the current scene.

scrubswithnosleeves | 2021-04-09 18:56

:bust_in_silhouette: Reply From: linklight2

I’ve had the same problem with autoload as well. I believe when you autoload something, it only brings access to the script and variables of the node, not its children, parents, or even the node itself. That’s why when you call any one of those get functions, its called from a null base. You’re using an autoloaded, null base node.

To fix, a general solution would be to just create an on-ready var of the node that you want in the specific nodes you need it in, and not in an autoloaded node.

Like so: onready var levelManager = get_node("/root/Node2D/levelManager") #change the getNode path to whatever you need

I believe when you autoload something, it only brings access to the script and variables of the node, not its children, parents, or even the node itself.

I’m sorry, can you expand on this? I don’t get it.

I’m not sure if I’m getting this right, but it seems that this assumes I’m calling get_tree().get_current_scene.get_name() from inside the singleton?

If it is, i’m calling the function from outside of it, from menu.gd and game.gd, not levelManager.gd

jagc | 2019-05-22 22:35

You’re right, I was assuming you were calling it from levelManager.gd. However, you do call your change scene function from levelManager, and maybe that’s why the scene change isn’t actually registering in your other nodes. Try unautoloading level manager, name the onready var levelManager (so you dont have to change code), and then retry it.

linklight2 | 2019-05-22 23:28

:bust_in_silhouette: Reply From: eons

Autoloaded scripts and scenes are being added before the first current scene is set up on the tree, you need to wait to check, or connect to the viewport’s root or the tree to get when the current scene is added.

One signal you can use is node_added on SceneTree, there are notifications too for Viewport(Node) changes.

I just read node_added in the documentation. It looks super useful! But i don’t know how to use it. XD
Can you give a short, simple example how to implement this?

jagc | 2019-05-24 09:22

:bust_in_silhouette: Reply From: hilfazer

It happens because _ready() gets called before new scene is set as a current scene.

get_tree().get_root().add_child(newscene) # _ready() is called here

get_tree().set_current_scene(newscene)

You can set new current scene when node enters SceneTree like this:

newscene.connect("tree_entered", get_tree(), "set_current_scene", [newscene], CONNECT_ONESHOT)

get_tree().get_root().add_child(newscene)

I presume menu.gd script is in your main scene and you’re not using levelManager to go to this scene. In that case Godot sets this scene as current on its own, which happens before _ready() and even before _enter_tree().

This makes sense when i saw the delay of the change when the tree was updating in the remote pane/window.

But i don’t understand how menu.gd is not using levelManager to change scenes? Because there is no other code that commands to change scenes except inside levelManager.

jagc | 2019-05-24 09:30

I mean you’re not changing current scene to menu.gd from other scene because your game starts with menu.gd. I could be wrong since i can’t see all of your code.

Are you changing a scene to menu.gd from anywhere in your code? I expect the same problem you’re having with game.gd if you do this.

hilfazer | 2019-05-24 19:19

You’re correct.

I’m having the same issue upon calling get_tree().get_current_scene().get_name() when changing from game.gd to menu.gd

This helped a lot. Thank you!

jagc | 2019-05-28 04:32