Reloading a scene instanced in the main scene

Godot Version

Godot 4

Question

Hello,

This is the first project I’m working on without following a tutorial so bear with me.
I’m trying to make a rogue like with procedurally generated rooms and doors (obviously).

In the main scene I’m placing the prefabricated rooms (or room currently). Inside the room I’m having a 4 doors which are looking for an adjacent room, if it doesn’t find one: queue_free.

The code works! but… in the main scene I have a simple code to reset it in order to see multiple generations:

func reload_level():
get_tree().reload_current_scene()

func _input(event):
if event.is_action_pressed(“ui_accept”):
reload_level()

When I reload the main scene, the rooms get placed but all doors disappear.
How should I go about fixing this issue?

In order to provide support it would be nice to know a little more about the context of your issue.

  • How does your scene tree look before and after reloading the scene?
    (supply an image or hierarchical list)
  • What does the script for the door look like?
    Full script or important snippets
  • What other key scripts exist in the scene?
    Script names and functionality summary

Without these details, I can only guess what the cause of your issue is.
Perhaps you forgot to set your Main scene as the current scene?
(e.g. GetTree().CurrentScene = scene;in C#)
I haven’t used GDScript

1 Like

Hopefully I can provide all information:

My World scene is the main scene, it’s simply a Node2D with a Walker script inside of it instancing rooms which are premade Node2Ds. It also has a Camera2D but that’s not important…

This is how it looks on the first run:
image
And after I run it a second time with the script provided in the first post (script that is inside the World script) the “StartingRoom” loads but the “Door” Node2D doesn’t load in (I can only post 1 image).

The problem I’m seeing is that the doors are no longer getting loaded in, this is suspect is caused by the fact that I’m calling “queue_free()” in the doors script:

extends Node2D

@onready var area_2d = $Area2D

var door_found = false

func _physics_process(_delta):
door_detection()

func door_detection():
if door_found == false:
queue_free()

func _on_area_2d_body_entered(body):
door_found = true

What I think I have to do is to also reload this scene when I reload the main World scene, but I’m not sure how…

I’m struggling to decipher the full context of your issue due to missing information.

I am noticing one potential problem though that may illuminate some misunderstanding you have with regards to the usage of _physics_process and _on_area_2d_body_entered.

Physics Process

_physics_process is a function that Godot provides in order to perform time-dependent physics logic, hence the _delta-parameter. The _physics_process, by default, runs at a rate of 60 updates per second.

In your case, you are using this function incorrectly as your logic is not required to be run more than once. You should be housing your logic entirely within a single function which should then be executed when needed, not in every physics update by _physics_process.

(On Area 2D) Body Entered

If I’m not mistaken, you’re using this signal from the area2D within your Door3-scene. While this is a valid way to detect whether a body is inside the area you have made for the door, you are not specifying that the body should be a door. With the way your code is written right now, even a wall could set door_found to true.

Execution order

I haven’t used Godot for very long so I can’t testify to the validity of how you split up the logic into 3 different functions. However, I am familiar with how important it is to know when functions run. In your script here, you have to verify that your _on_area_2d_body_entered function runs before the _physics_process function - otherwise the door will be removed before detecting a possible door.

Final notes

I cannot stress enough how important it is for someone at your level to fully explain the context of your problem. People want to help you but it’s very hard to do so when information is missing. I know you had an image limit for the post but it takes no time to boot up Microsoft Paint and stitch two images into one. It would also be nice if your code snippet was formatted such that it would be easier to read (using tabs and/or spaces).

I would suggest a few things for you:

  • Start doing some debugging on your own. Insert some print-statements in a few places to verify that the code runs in the correct order.
  • Print out important variable values (like your door_found) to determine whether its value is what you expect.
  • Watch some tutorials. There’s nothing wrong with copying in the beginning. The more you do it, the sooner you will start to piece together how it all works.

I wish I could help you more than that.

1 Like

As far as I know reload_current_scene should reload all nodes, including the previously freed ones.
As @Sweatix said, make sure you’re not deleting your doors before the body_entered signal has a chance to trigger.
You could wait for a 1 second timer before you delete them just to test it:

func _ready():
    door_detection()

func door_detection():
    await get_tree().create_timer(1.0).timeout
    if door_found == false:
        queue_free()
1 Like

Thanks for your help guys.
You thought me some valuable things, @Monday was correct. I was deleting the doors before having the change to check if it has a adjacent door.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.