Adding instances of scenes with buttons from autoloaded scripts breaks signal

Godot Version

Godot Engine v4.2.1.stable.official [b09f793f5]

Question

This is a possible bug, but before I submit a report I thought I would ask here just to make sure.

In the Main Scene, I can instantiate an asset that has a button attached to it.

Scene layout:
_Node2D (script)
|_Button (calls script.method)

On script:
@onready var myScene = preload(“res://path/to/myScene.tscn”)
func _ready():
var instance = myScene.instantiate()
add_child(instance)

The scene shows as desired, and the buttons in the scene work. Now, if I move this code to a script that is autoloaded, the scene shows up just the same but the buttons do not work. The buttons show, but their signals do not go through.

I should mention that I am using the preloaded script as a static singleton. I am not instantiating the preloaded script, just calling methods on it. This might be the issue, but if so then how do I make proper globally accessible singletons?

I found a work around by adding the nodes to the tree directly:

get_tree().root.get_node(“DesiredParent”).add_child(node)

But I’m still curious why the buttons would not work otherwise…

Can you show your Autload panel? The preload in your example is a scene, not a script. Are you autoloading a tscn? Or trying to manually instantiate with a gd?

Try loading the res://path/to/myScene.tscn instead.

There is no tscn associated with the singleton class. It’s just a script. The tscn that I am instantiating with instantiate() is a scene with a tscn. Apologies on the error in my last message. @gertkeno, not trying to be rude, but do you get what I mean when I say that I’m creating a singleton class in the global namespace? Every framework has their own way of describing things, and Godot does not have static. But I do see in the docs that autoload is intended as a way to create singletons, which is what I’m going for. It’s odd to me that everything else in the singleton class is working fine, just not instantiating scenes with pre-configured signals.

The code you posted works just fine. I tested it locally. So there’s something else going on. Please post more context. Relevant scripts, configuration, scene structures, etc.

1 Like

Godot does have static in 4.2.

I don’t think you are giving us the whole picture, The script example you posted can be reduced by putting whatever script you need on the root node of res://path/to/myScene.tscn and autoloading that scene instead of just the script. The script example also has no signals or connections so it’s impossible to discern a signal/connection related error from it.

1 Like

I’m sorry, @gertkeno @indicainkwell , I really did not explain this well enough. But there definitely is an issue here. I’ve reproduced the error in a new repo which you can find at GitHub - gavinraym/Godot4.2SignalTest: Demonstrating error with autoloaded scripts instantiating buttons.

Let me try and explain it a bit better too. There is a scene that I am instantiating which has a control node root and a button that calls the control node’s script. If I instantiate the scene from the main scene, it loads in and works fine. But if I instantiate the scene from an autoloaded script, it looks fine but the button does not work. Does that make more sense now?

1 Like

The code is fine, I agree. The issue is with a loss of signals when the scene is loaded from an autoloaded script.

2024-06-11-213014_262x301_scrot

You are adding the button as a child of the singleton, so the Control node overlaps it.

2 Likes

Thanks! I did not realize the Control node would block mouse clicks. But it makes sense!

Screenshot (50)
After setting the Mouse filter to Ignore on the Main Scene’s Control node, the click events are able to pass through and the button works.

1 Like