Godot Version
4.x
Question
The docs mention that Global Singletons are not the same as Autoloads but it doesn’t specify how exactly they differ.
We can use Engine.register_singleton()
to manually add Singletons at runtime that will, with one line of code, behave just like an Autoload.
var signal_bus: Object = load("res://signal_bus.gd").new()
Engine.register_singleton("SignalBus", signal_bus)
This should allow us to use SignalBus
globally. However, because we are registering it at runtime, we cannot make use of said feature in the editor (since it’s not yet registered).
In order to access it, we need to fetch it using:
var signal_bus: Object = Engine.get_singleton("SignalBus")
Now it will work as intended and we can use any of the methods/signals/properties available to the class.
There is at least one other problem with this approach. It bricks the autocomplete feature, since it doesn’t know what the Object has access to.
To fix this, we can simply use class_name SignalBus
in the script file we want to register (in this case signal_bus.gd
), and then refactor the above to:
var signal_bus: SignalBus = load("res://signal_bus.gd").new()
Engine.register_singleton("SignalBus", signal_bus)
var singal_bus: SignalBus = Engine.get_singleton("SignalBus")
Works as intended, but it looks like there should be a naming conflict between the Singleton named SignalBus
and the Class named SignalBus
.
There sure is one when you try to do the same for Autoloads:
I am unsure if this is a bug or intended, since there is no mention of what the differences are between Global Singletons and Autoloads. I assume as long as it works it should be fine. Changing one of the names just to be 100% certain is also fine.