Godot Version
Godot 4.4.1
Question
Hi, guys, I’m encountering an issue with switching scenes manually. Here is the code for my game manager script, which is an autoload script.
extends Node
var area_path = "res://Assets/Scenes/Areas/"
var first_level = preload("res://Assets/Scenes/Areas/Level 1.tscn")
var new_one = first_level.instantiate()
var second2_level = preload("res://Assets/Scenes/Areas/Level 2.tscn")
var new_two = second2_level.instantiate()
var in_brewery = preload("res://Assets/Scenes/Areas/Brewery Interior.tscn")
var new_in = in_brewery.instantiate()
var leave_brewery = preload("res://Assets/Scenes/Areas/Brewery.tscn")
var new_out = leave_brewery.instantiate()
func next_level():
get_tree().current_scene.queue_free()
add_child(new_one)
print("Entered!")
func second_level():
get_tree().current_scene.queue_free()
add_child(new_two)
func into_brewery():
get_tree().current_scene.queue_free()
add_child(new_in)
func out_brewery():
get_tree().current_scene.queue_free()
add_child(new_out)
The thing is, the function “next_level” works, but the other function returns with the bug "Cannot call method queue_free() on a null value. I’m not sure it’s an autoload problem or something; I can not figure it out. My target here is to keep the UI state when switching scenes, so I’m not using change_scene_to_file().
I will be very appreciative of any help.
I recommend keeping a reference to the current scene, instead of relying on current_scene to do that for you, as it might not work right in every single case, depending on what you expect it to happen, but in more simple scenarios, you can probably get away with it.
Also, a bigger problem, is that you only ever instantiate scenes ONCE, then never again. This can very much cause weird behaviour like that.
So in your case, I’d recommend doing the following:
extends Node
var area_path = "res://Assets/Scenes/Areas/"
var first_level = preload("res://Assets/Scenes/Areas/Level 1.tscn")
var second2_level = preload("res://Assets/Scenes/Areas/Level 2.tscn")
var in_brewery = preload("res://Assets/Scenes/Areas/Brewery Interior.tscn")
var leave_brewery = preload("res://Assets/Scenes/Areas/Brewery.tscn")
func next_level():
get_tree().current_scene.queue_free()
var new_one = first_level.instantiate()
get_tree().root.add_child(new_one)
get_tree().current_scene = new_one
print("Entered!")
func second_level():
get_tree().current_scene.queue_free()
var new_two = second2_level.instantiate()
get_tree().root.add_child(new_two)
get_tree().current_scene = new_two
func into_brewery():
get_tree().current_scene.queue_free()
var new_in = in_brewery.instantiate()
get_tree().root.add_child(new_in)
get_tree().current_scene = new_in
func out_brewery():
get_tree().current_scene.queue_free()
var new_out = leave_brewery.instantiate()
get_tree().root.add_child(new_out)
get_tree().current_scene = new_out
1 Like
Thanks a lot for the help. I can switch scenes without any problem right now. But if possible, I want to ask one more thing. It seems like the UI is not staying in its state when switching scenes. Here is my code for the UI script. Can you help me with that too please?
extends Control
class_name HUD
@export var logs_label : Label
@export var stone_label: Label
@export var hop_label:Label
@export var potato_label:Label
@export var reminder: Label
var logs_total: int = 0
var stones_total: int = 0
var hops_total: int = 0
var potatoes_total: int = 0
func update_logs_label(logs_collected: int):
logs_total += logs_collected
logs_label.text = "x " + str(logs_total)
func update_reminder():
reminder.text = "Collect materials and ingredients!"
func update_inter():
reminder.text = "Press E to make alcohol. Press Q to exit brewery."
func update_stone_label(stones_collected: int):
stones_total += stones_collected
stone_label.text = "x " + str(stones_total)
func update_hop_label(hops_collected: int):
hops_total += hops_collected
hop_label.text = "x " + str(hops_total)
func update_potato_label(potatoes_collected: int):
potatoes_total += potatoes_collected
potato_label.text = "x " + str(potatoes_total)
For example, if I picked up a log at Level 1, the label for the log shows “x1”, but when I switch scenes, it will become “x0” again instead of staying as “x1”.
Is your UI code connected to your player scene? If so, I recommend either keeping it in a seperate scene that you ONLY ever instantiate once on the root then never queue_free it, or create a function that saves all the current data on it to a file, then loads it back up every time you switch scenes. I’d recommend the first approach, as it seems like a much more simple solution in your case right now.
Yes, I use the first solution and it works! Thanks for your generous help!
1 Like