Check out our latest project ✨ OpenChapter.io: free ebooks the way its meant to be πŸ“–

Resource Based Signal Bus

An asset by camperotactico
The page banner background of a mountain and forest
Resource Based Signal Bus thumbnail image
Resource Based Signal Bus thumbnail image
Resource Based Signal Bus thumbnail image
Resource Based Signal Bus thumbnail image
Resource Based Signal Bus hero image

Quick Information

0 ratings
Resource Based Signal Bus icon image
camperotactico
Resource Based Signal Bus

This asset allows for signal communication between nodes without direct references to each other or to a singleton class.Each signal is contained inside its own resource and can be saved into the "res://" directory. They can be assigned to scripts from the inspector, just like any other exported variables.The asset includes two other goodies:1- "Signal Bus Listener": A node that is used to create responses to signals straight from the inspector, without any code.2- "Custom SignalBus Script Editor": An editor tool that can be used to create signal buses that take one or more arguments.(Other advantages of signal buses over singletons and regular signals are explained in the README.md file included with the asset and available in the git repository.)

Supported Engine Version
4.5
Version String
1.1
License Version
Apache-2.0
Support Level
community
Modified Date
8 hours ago
Git URL
Issue URL

Resource Based Signal Bus

README Asset Library README Made with Godot README Mastodon Follow README Kofi

A "Signal Bus" (usually known as "Event Bus" or "Event Channel") is a middleman in the Observer Pattern. It allows objects to send and receive events (or signals, in the case of Godot) without being directly referenced with each other.

In Godot, a common approach to achieve this is to create a singleton that holds all the signals the nodes of a project can access. This asset offers a better, different approach.

Inspired by the usage of ScriptableObject assets as event channels in the Unity3D engine (learn about this here and here), in this asset each signal is contained inside its own resource, a SignalBus. These can be created and saved into the res:// directory like any other resource type.

README A screenshot of the _Godot_ editor showing the code to emit and receive signals through signal buses.

A screenshot of the Godot editor showing the code to emit and receive signals through signal buses.

Instead of connecting/emitting signals through a singleton, a node exports a variable that points to a SignalBus resource and connects/emits through it instead. Some of the benefits of using this approach over regular signals or a singleton are:

  • βœ… Decoupled and Maintainable Design: Emitter and receiver nodes do not hold references to each other or to a global script. Signals are independent from the rest of the code. If an emitting script needs to be refactored, renamed or split into smaller pieces, there is no need to fix broken connections on the receiving nodes.

  • βœ… Modular and Scalable: Scenes do not have to be referenced or modified to include new functionality. Any new node that references an existing SignalBus will interact with the rest of the scenes that already use it.

  • βœ… Easy to Test: Because these signal buses are resources, they can be assigned to variables, and they can be created, replaced and destroyed via code. When writing tests, ensure a game component work as expected by creating and assigning temporary signal buses instead of instantiating all of its dependencies. Assign the signal buses to the component and use them to emit or monitor signals.

  • βœ… Flexible and Granular: Each signal bus resource is unique from the rest, even if it shares the same SignalBus derived type. A set of nodes can communicate using the same signal bus, or each have its own isolated one.

  • βœ… More Visual: Signals are now just another asset in the res:// folder. Designers and artists can use them in their scenes without any coding. On top of that, trying to delete a SignalBus resource will warn about scenes that use them becoming orphan.

🧰 Features

The most basic element of this asset, the script that defines the resource class that wraps the signal, is nothing special. A simplified version of it would look something like this:

extends Resource

# The actual implementation in the asset is a bit more complex, as it makes use
# of the Godot 4.5 @abstract keyword and features an additional method to allow
# the included node "SignalBusListener" to respond to this resource in the inspector
class_name SignalBus

singal _signal()

func add_connection(callable: Callable) -> void:
  _signal.connect(callable)

func remove_connection(callable: Callable) -> void:
  _signal.disconnect(callable)

func emit() -> void:
  _signal.emit()

Copying that script into a project would replicate some of the functionalities and advantages of this asset. However, the project will be missing out on some of the goodies that I included to make the development easier:

  • In this asset, each resource instance is typed. The SignalBus class itself is abstract, which means no resource can be created from it. To be able to create a resource, a typed script that extends SignalBus needs to be created. Out of the box, this addon comes only with a resource type for a signal with no arguments, VoidSignalBus.

  • A Custom SignalBus Script Creator tool is included to help define new resource types for signals that take one or more parameters. By default, this tool is displayed in the left upper right dock of the Godot editor, next to the Scene and Import tabs.

  • Custom implementations can be manually created as well by extending the SignalBus class on a new script. The package includes a Script Template to ease this process, but it still involves some manual work.

  • The asset also features a new node named SignalBusListener. Its purpose is to allow designers and artists to create responses to signals from the inspector. It connects a SignalBus resource to a method of a target Node in the scene. This new node allows to forward, ignore or add new arguments to the received signal. SignalBusListener filters and displays automatically the methods from the target Node that are compatible with the received (and modified) signal.

⬇️ Installation

  1. Download the asset from the AssetLib tab in the Godot Editor.

  2. Enable the plugin Project -> Project Settings -> Plugins -> Resource Based Signal Bus

πŸ“– Usage

Creating and using SignalBus resources.

README A screenshot of the _Create New Resource_ window of the Godot editor showing different signal bus types.

A screenshot of the Create New Resource window of the Godot editor showing different signal bus types.

  1. Right click on the FileSystem panel, then select Create New -> Resource. A pop-up will open. In there, search for SignalBus and choose a type.

  2. To emit a signal through its bus, export a variable that matches the SignalBus type in a script. In the inspector panel, choose the resource to use. Finally, call the emit(...) method providing the required arguments.

  3. To receive a signal through its bus, export a variable that matches the SignalBus type in a script. In the inspector panel, choose the signal bus to use. Then override the _enter_tree() and _exit_tree() methods and use them to connect and disconnect from to the signal bus using add_connection(...) and remove_connection(...) and provide them with the callback to use.

Using the SignalBusListener node.

  1. Right click on the Scene panel, then select Add Child Node.... A pop-up will open. In there, search for SignalBusListener and press Create.

  2. In the inspector panel, select a SignalBus to listen to and a target node to send a response. The arguments from the received signal can be forwarded, ignored or extended by using the different available controls. Once the configuration for the arguments is ready, pick a compatible method from the Callable String Name option button.

    README A screenshot of the Godot editor showing the listener node responding to a signal and including extra arguments.

    A screenshot of the Godot editor showing the listener node responding to a signal and including extra arguments.

Creating Custom SignalBus Scripts From The Editor.

The easiest way to create a new script for a custom SignalBus type is to use the tincluded editor tool.

README A screenshot of the _CreateCustomSignalBusScriptEditor_ tab of the Godot editor. The tool is filled with parameters to create a custom signal bus type that wraps a `String,Array[Vector3]` signal.

A screenshot of the CreateCustomSignalBusScriptEditor tab of the Godot editor. The tool is filled with parameters to create a custom signal bus type that wraps a String,Array[Vector3] signal.

  1. In the Godot editor, click on the CustomSignalBusScriptEditor tab on the right dock at the left side of the screen, next to the Scene and Import tabs.

  2. Set the directory where the new script will be created to.

  3. Set the number of arguments the contained signal will use.

  4. Change the type of the arguments.

    TYPE_OBJECT, TYPE_ARRAY and TYPE_DICTIONARY arguments will reveal an optional field where a specific type can be entered. In the above picture, the second argument references a Vector3 typed Array. Arrays and dictionaries can feature nested arrays and dictionaries as well.

    As an example, to set a Dictionary[int,Array[CharacterBody3D]] typed argument, the variant type needs to be set to TYPE_DICTIONARY and the optional field to int,Array[CharacterBody3D]

  5. Click the Create Script button.

  6. To create and use the new SignalBus type, simply follow the steps above.

Creating Custom SignalBus Scripts Via Code.

  1. Right click on the FileSystem panel, then select Create New -> Script. A pop-up will open. Fill in the different fields so the new class inherits SignalBus and uses the custom template included in the asset. Click Create.

    README A screenshot of the script creation pop-up. In this case, I am going to create a signal that takes two arguments: an int and a Dictionary[String,Color]

    A screenshot of the script creation pop-up. In this case, I am going to create a signal that takes two arguments: an int and a Dictionary[String,Color] .

  2. Once the new script is created, the editor will complain about several errors. This is because some placeholders in the class need to be changed to match the signature of our custom signal.

    README A screenshot of the Godot editor showing a bunch of compiler errors when a custom `SignalBus` class is created.

    A screenshot of the Godot editor showing a bunch of compiler errors when a custom SignalBus class is created.

    README A screenshot of the Godot editor showing the custom `SignalBus` class after the placeholders have been replaced with the desired types.

    A screenshot of the Godot editor showing the custom SignalBus class after the placeholders have been replaced with the desired types.

  3. To create and use the new SignalBus type, simply follow the steps above.

πŸ› Limitations, known issues, bugs

Perhaps the biggest limitation of this project is that I haven't found a way to emit signals from the editor while the game is running. This would be an amazing addition which would ease the testing while developing a project.

This asset allows for signal communication between nodes without direct references to each other or to a singleton class.

Each signal is contained inside its own resource and can be saved into the "res://" directory. They can be assigned to scripts from the inspector, just like any other exported variables.

The asset includes two other goodies:
1- "Signal Bus Listener": A node that is used to create responses to signals straight from the inspector, without any code.
2- "Custom SignalBus Script Editor": An editor tool that can be used to create signal buses that take one or more arguments.

(Other advantages of signal buses over singletons and regular signals are explained in the README.md file included with the asset and available in the git repository.)

Reviews

0 ratings

Your Rating

Headline must be at least 3 characters but not more than 50
Review must be at least 5 characters but not more than 500
Please sign in to add a review

Quick Information

0 ratings
Resource Based Signal Bus icon image
camperotactico
Resource Based Signal Bus

This asset allows for signal communication between nodes without direct references to each other or to a singleton class.Each signal is contained inside its own resource and can be saved into the "res://" directory. They can be assigned to scripts from the inspector, just like any other exported variables.The asset includes two other goodies:1- "Signal Bus Listener": A node that is used to create responses to signals straight from the inspector, without any code.2- "Custom SignalBus Script Editor": An editor tool that can be used to create signal buses that take one or more arguments.(Other advantages of signal buses over singletons and regular signals are explained in the README.md file included with the asset and available in the git repository.)

Supported Engine Version
4.5
Version String
1.1
License Version
Apache-2.0
Support Level
community
Modified Date
8 hours ago
Git URL
Issue URL

Open Source

Released under the AGPLv3 license

Plug and Play

Browse assets directly from Godot

Community Driven

Created by developers for developers