Signaling from a newly instanced node

Godot Version

4.6.2

Question

I want to implement buttons that switch screens when clicked. Right now my Main node looks like this:

image

I’ve implemented a button in MainMenu that when clicked, tells Main to delete MainMenu and instantiate another node MainGame as a child.

Now I want to implement a button in MainGame for the opposite function: delete MainGame and instantiate MainMenu. However, since MainGame wasn’t originally a part of the tree, I couldn’t connect a signal from there to Main through the signals tab. I tried something like

return_to_main_menu.connect($MainMenu.get_parent().return_to_menu())
return_to_main_menu.emit()

But that didn’t work.

I know I could add MainGame to the original tree and do some changes, but before I do that, I want to know if there’s a way to do what I want with what I have.

“Didn’t work” in what way?

It returns errors:

E 0:00:48:789   main_game.gd:540 @ process_click(): Node not found: "MainMenu" (relative to "/root/Main/MainGame").
  <C++ Error>   Method/function failed. Returning: nullptr
  <C++ Source>  scene/main/node.cpp:1963 @ get_node()
  <Stack Trace> main_game.gd:540 @ process_click()
                main_game.gd:505 @ _on_click_button()
                button.gd:17 @ _on_area_2d_input_event()
E 0:00:48:791   process_click: Cannot call method 'get_parent' on a null value.
  <GDScript Source>main_game.gd:540 @ process_click()
  <Stack Trace> main_game.gd:540 @ process_click()
                main_game.gd:505 @ _on_click_button()
                button.gd:17 @ _on_area_2d_input_event()

image

i’ve tested it, it’s probably bug with your code cuz you can emit newly connected signal

extends Node

var test = preload(“res://Other/test_node_2.tscn”)

func hello():
print(“hello”)

func _ready():
var new = test.instantiate()
add_child(new)
new.hello.connect(hello)
new.hello.emit()

Well then fix the error, following the error message. It says that it cannot find the node on the specified path, meaning that you provided an incorrect node path.

How are you instantiating these new MainGame and MainMenu scenes? If you are using a preload it is likely a circular dependency which silently fails and becomes null.

Is there any reason you cannot use get_tree().change_scene_to_file()? It is built to do such operations, may prove easier than managing your own “main” node.

Yeah, doing this worked. Thank you!

I tried the function but it replaced the entire tree including Main with MainGame, which is not what I wanted (I wanted MainMenu to be replaced with MainGame).

Right, but can Main be an autoload/global? Can you explain more big-picture what you are trying to do? Are you using preload in your scripts?