Before going further, let me state that this tutorial is intended for absolute beginners who have no idea about signals and finding a hard time following the official documentation.
There are times we need to use some type of notification services. Whether the player hits an enemy or player health reached zero, be it anything, we require other areas of the game to be notified of those. We don't want to write functions for each and every object and call it from somewhere. It will be so horrible that when you return the next day morning, you will throw your project. In this article, we will look what are Godot signals and how the signals can be used for better separation between game objects.
If you looked into the physics related nodes, you already know a basic idea of how signals work. A RigidBody2D has many signals associated with it.
Since RigidBody2D is inherited, all of its ancestors' signals are also available. These signals are emitted whenever its related event occurs. For eg, the signal 'body_enter' signal is emitted when the RigidBody2D collides with another physics object. If we listen to the signal,
connect("body_enter",self,"_collided_with_something") func _collided_with_something(otherbody): print("Collided with ", otherbody)
whenever it collides with any other object, the function which is passed as the third parameter in the connect API is called. The second parameter denotes where the callback function is defined. Signal callbacks can have arguments so that we get the details of the event. In this condition, we get the other collided body.
Custom Signals
We can create our own signals whenever needed, this helps in creating independent game objects. In our games, we require some type of UI to display the game status. Let us say we need a player health OSD. Let us look two scenarios,
- UI update code is written inside the player script and it will call it whenever player health is updated.
- Player emits a signal, UI script listens for it and update themselves.
Which one do you think elegant?
If at a later time, we want the player to be in a section where no UI exists, we would want to change the player script to include some condition checking in place. What happens if there are many of these conditions involved?
When signals are used to communicate, other elements can update themselves without depending on any other element. Removing an element or themselves won't make any problem in our game.
Godot signals for beginners tutorial Click To Tweet
Creating a custom signal
We can define a signal like this on the top of your script where we define variables.
signal playerhurt
Then when player is hurt, we emit the signal
emit_signal("playerhurt")
Now other elements can listen for this signal
player.connect("playerhurt",self,"_on_player_hurt")
From my experience, you should use constants for signals instead of strings.
const SIGNAL_PLAYER_HURT = "playerhurt" signal playerhurt emit_signal(SIGNAL_PLAYER_HURT)
And inside other scripts,
player.connect(player.SIGNAL_PLAYER_HURT,self,"_on_player_hurt")
Where can you use signals
Signals can be used wherever we prefer want to separate two objects depending on each other. Common use cases of signals are,
In this article, I showed how to use signals inside scripts. I recommend you to use signals via code because it will be easier to apply the same scripts to another object and it just works. Sometimes we forget to add the signals in the editor and start to find why the callbacks are not firing. Thanks for reading.
[Total: 0 Average: 0/5]