3 Simple Ways to Communicate Between Nodes in Godot

There are several ways you can establish communication between nodes in Godot. It really depends on the relationship between the nodes and the scenes they are found in.

This article talks about forms of node communication in Godot. If that is a source of frustration for you, you might benefit from reading this article. It is written in simple terms with examples so everyone, even beginners, can quickly understand.

Illustration of node communication in Godot

Ways to Communicate and Pass Data Between Nodes in Godot

These are the three most common ways of communicating and passing data between nodes. There might be other methods, but they are probably more unconventional and not recommended for the average game developer.

1. Direct Node Reference

A direct node reference is a form of direct communication between nodes. In this case, a node calls another node’s functions or members and potentially passes some data to it. To obtain a reference to a node, you must use the get_node(path) method (or alternatively use the ‘$’ sign). Once you have the node reference, you can directly invoke any of its available methods or modify its members.

The benefit of this communication mode is that it’s simple to implement and fast to execute. On the other hand, since it’s a direct call to another node, you can only communicate with one node at a time.

2. Signals

Signals are an indirect form of communication, relying on the Observer design pattern. By using signals, you can establish a communication channel between two nodes by registering a callback method in one node that will be called when an event happens on another node.

For example, an Area2D node can signal its parent node that the mouse has entered or exited a marked area. Upon receiving the event, the parent node can trigger some action in response to this mouse event, such as highlighting the area using another node, printing information about the object, or even executing logic to prepare for a potential click on the object.

The great benefit of this communication method is that the target node receives a notification as soon as the event happens. Another cool thing about signals is that the source and target objects don’t actually know each other and are not aware of the exact type of each other. This makes the code very flexible and maintainable in the long run.

In case you have several objects that need to be notified when a certain event happens, you could connect multiple methods to the same signal, where each method is handled by a different object or node.

For a more extensive overview of signals, visit the How to Use Signals for Node Communication article.

3. Global Objects

A global object, such as an autoloaded node, can act as a communication channel between nodes. Although this is not recommended and can make the code messier, it is possible. The idea here is that global variables, which can be accessed from anywhere in the code, hold information that is updated by one node and then used by another node. It acts as a sort of bridge between the nodes.

The benefit of this architecture is that you are not limited to just two nodes. A global object can be a source of information for multiple nodes and can be modified by multiple nodes. Unfortunately, this is also its drawback. If any object can modify this global data, it opens a door to potential bugs. Another downside to this method is that the node receiving the information is not notified in real time, as opposed to signals, where the signal is emitted the moment the event happens.

This communication channel works well for very specific use cases, such as communicating or passing data between scenes that are not loaded in memory at the same time. When switching scenes, all scene data is removed from memory, and the new scene is loaded. A global object is always found in memory and can help pass information during the scene transition.



How Do You Actually Communicate Between Nodes in Godot?

The truth is that most node communication is direct, but some of the communication must be a combination of direct reference, signals, and global objects. There are several types of node relationships in Godot. Let’s examine the most common types and explore the best form of communication in each case.

1. Parent Node to Child Node in the Same Scene

A parent node can directly communicate with its children via their reference. The parent simply calls a method or a member of the child.

extends Node2D
class_name World

@onready var m_NodeMusicTrack : AudioStreamPlayer = get_node("Music")

func _ready():
    # Directly call the 'play' method of the audio stream player
	m_NodeMusicTrack.play()

2. Child Node to Parent Node in the Same Scene

While it is possible for a child node to access its parent, it’s uncommon and confusing. A better way to establish communication between a child node and a parent node is using signals. The child can define a signal and pass some data alongside it. Since the parent has direct access to the child, it can connect to the child’s signal and receive notification when an event happens in the child node. The signal doesn’t have to be a custom one, it can be a built-in signal as well.

extends Node2D
class_name World

@onready var m_NodePlayer : CharacterBody2D = get_node("Player")		# Direct reference to the Player node
@onready var m_NodeSpikes : Area2D = get_node("Spikes")					# Direct reference to the Spikes node

func _ready():
	# Connect the spikes collision events to the _OnSpikesCollision callback method
	m_NodeSpikes.body_entered.connect(_OnSpikesCollision)
	
# Handler for spikes collision events
func _OnSpikesCollision(body) -> void:
	if (body is Player):
		# The colliding body is the player
		m_NodePlayer.InflictDamage(Player.DAMAGE_10_HP)

In this example, the ‘World’ node is the parent, and the ‘Player’ and ‘Spikes’ nodes are its children. The body_entered signal of the spikes node is connected to the _OnSpikesCollision(body) method found in the world node. Each time a body enters the area of the spikes, a signal will be emitted, and the _OnSpikesCollision(body) method will be called. Inside this method, the world node handles the result of the collision, in this case, checking that the colliding body is the player and inflicting him with a certain amount of damage.

3. Child Node to Child Node in the Same Scene

This is a more complex situation since every node can only get a direct reference to its children, so neither direct reference nor signals will work here.

So what can we do here? Use a combination of those two methods. First, send a signal from the source node up to its parent, and then call the target node directly from the parent.

4. Node in One Scene to a Node in Another Scene

In this case, the solution depends on the types of scenes.

  • Both scenes are loaded into memory at the same time: Use signals to communicate and pass data up the chain of parents, and then use direct access down the chain of children.
  • Scenes are not loaded at the same time in memory: You will have to use a global entity to store the information. The node that is currently loaded in memory stores information in the global object, then the scene is released from memory, and finally, the newly loaded scene grabs the information stored in the global object. For instance, the player wants to load a saved game. The path of the saved game file must be transferred from the menu scene to the game level scene and loaded from there. Since the menu and level scenes don’t exist in memory at the same time, a global management object must be created to store the selected file path.

5. Node in a Local Scene to a Node in a Global Scene

A global (autoloaded) scene can be accessed from anywhere in the code, which means you can invoke methods and use members of the global node directly from your local scene and nodes.

My Take on Node Communication in Godot

Deciding which form of communication is best for each situation affects the overall architecture of your game, making these decisions very important. After all, you don’t want to change the relationships between nodes each time a change in game requirements comes along.

The Night Quest Games Blog is a great resource for game developers, especially Godot users. There are many tutorials and guides there that will make you a better game developer, designer, and code architect. I have spent many hours writing and fine-tuning these articles, so take advantage of them as much as you can. Good luck!

If the information in this article was helpful to you, please consider supporting this blog through a donation. Your contributions are greatly appreciated and allow me to continue maintaining and developing this blog. Thank you!

Leave a Comment

Your email address will not be published. Required fields are marked *