Signal
Un type intégré représentant un signal d'un Object.
Description
Signal est un type Variant intégré qui représente un signal d'une instance Object. Comme tous les types Variant, il peut être stocké dans des variables et transmis à des fonctions. Les signaux permettent à tous les Callables connectés (et par extension leurs objets respectifs) d'écouter et de réagir aux événements, sans se référencer directement l'un l'autre. Cela permet de garantir la flexibilité du code et de simplifier sa gestion. Vous pouvez vérifier si un Object possède un nom de signal spécifique grâce à Object.has_signal().
En GDScript, les signaux peuvent être déclarés avec le mot-clé signal. En C#, vous pouvez utiliser l'attribut [Signal] sur un délégué.
signal attaque
# Des arguments supplémentaires peuvent être déclarés.
# Ces arguments doivent être transmis lors de l'émission du signal.
signal item_dropped(nom_objet, montant)
[Signal]
delegate void AttackedEventHandler();
// Des arguments supplémentaires peuvent être déclarés.
// Ces arguments doivent être passés lors de l'émission du signal.
[Signal]
delegate void ItemDroppedEventHandler(string nomObjet, int montant);
Connecter des signaux est l'une des opérations les plus courantes dans Godot, et l'API offre de nombreuses options pour ce faire, décrites plus loin. Le bloc de code ci-dessous illustre l'approche recommandée.
func _ready():
var bouton = Button.new()
# `button_down` est un type Variant de Signal. Nous appelons ainsi la méthode Signal.connect(), et pas Object.connect().
# Voir la présentation ci-dessous pour une discussion plus en détail de l'API.
bouton.button_down.connect(_on_button_down)
# Cela suppose qu'une classe `Joueur` existe, et qui définit un signal `touche`.
var joueur = Joueur.new()
# Nous utilisons encore Signal.connect(), et nous utilisons aussi la méthode Callable.bind(),
# qui renvoie un nouveau Callable avec les paramètres liés.
joueur.hit.connect(_lorsque_joueur_touche.bind("épée", 100))
func _on_button_down():
print("Bouton appuyé !")
func _lorsque_joueur_touche(type_arme, degats):
print("Touché avec l'arme %s pour %d dégâts." % [type_arme, degats])
public override void _Ready()
{
var bouton = new Button();
// Le C# prend en charge le passage de signaux en tant qu'événements, nous pouvons donc utiliser cette construction idiomatique :
bouton.ButtonDown += OnButtonDown;
// Cela suppose qu'une classe `Joueur` existe, et qui définit un signal `touche`.
var player = new Player();
// Nous pouvons utiliser des lambdas lorsque nous devons lier des paramètres supplémentaires.
player.Hit += () => LorsqueJoueurTouche("sword", 100);
}
private void OnButtonDown()
{
GD.Print("Bouton appuyé !");
}
private void LorsqueJoueurTouche(string typeArme, int degats)
{
GD.Print($"Touché avec l'arme {typeArme} pour {typeArme} dégâts.");
}
``Object.connect()`` ou ``Signal.connect()``?
Comme nous l'avons vu plus haut, la méthode recommandée pour connecter les signaux n'est pas la méthode Object.connect(). Le bloc de code ci-dessous montre les quatre options de connexion des signaux, en utilisant soit cette ancienne méthode, soit la méthode recommandée connect(), et en utilisant soit un Callable implicite, soit un Callable défini manuellement.
func _ready():
var bouton = Button.new()
# Option 1 : Object.connect() avec un Callable implicite pour la fonction définie.
bouton.connect("button_down", _on_button_down)
# Option 2 : Object.connect() avec un Callable construit en utilisant un objet cible et un nom de méthode.
bouton.connect("button_down", Callable(self, "_on_button_down"))
# Option 3 : Signal.connect() avec un Callable implicite pour la fonction définie.
bouton.button_down.connect(_on_button_down)
# Option 4 : Signal.connect() avec un Callable construit en utilisant un objet cible et un nom de méthode.
bouton.button_down.connect(Callable(self, "_on_button_down"))
func _on_button_down():
print("Bouton appuyé !")
public override void _Ready()
{
var bouton = new Button();
// Option 1 : En C#, nous pouvons utiliser les signaux comme des événements et s'y connecter avec cette syntaxe idiomatique :
bouton.ButtonDown += OnButtonDown;
// Option 2 : GodotObject.Connect() avec un Callable construit à partir d'un groupe de méthodes.
bouton.Connect(Button.SignalName.ButtonDown, Callable.From(OnButtonDown));
// Option 3 : GodotObject.Connect() avec un Callable construit en utilisant un objet cible et un nom de méthode.
bouton.Connect(Button.SignalName.ButtonDown, new Callable(this, MethodName.OnButtonDown));
}
private void OnButtonDown()
{
GD.Print("Bouton appuyé !");
}
Bien que toutes les options aient le même résultat (le signal BaseButton.button_down de bouton sera connecté à _on_button_down), l'option 3 offre la meilleure validation : elle affichera une erreur à la compilation si le Signal button_down ou le Callable _on_button_down ne sont pas définis. En revanche, l'option 2 ne s'appuie que sur des noms de chaînes et ne pourra valider l'un ou l'autre nom qu'à l'exécution : elle générera une erreur à l'exécution si « button_down » n'est pas un signal, ou si « _on_button_down » n'est pas une méthode dans l'objet self. La principale raison d'utiliser les options 1, 2 ou 4 serait si vous avez besoin d'utiliser des chaînes de caractères (par exemple pour connecter des signaux de manière programmatique sur la base de chaînes de caractères lues dans un fichier de configuration). Sinon, l'option 3 est la méthode recommandée (et la plus rapide).
Lier et passer des paramètres :
La syntaxe pour lier des paramètres est Callable.bind(), qui renvoie une copie du Callable avec ses paramètres liés.
Lors de l'appel de emit() ou de Object.emit_signal(), les paramètres du signal peuvent également être transmis. Les exemples ci-dessous illustrent la relation entre ces paramètres de signal et les paramètres liés.
func _ready():
# Cela suppose qu'une classe `Joueur` existe, et qui définit un signal `touche`.
var joueur = Joueur.new()
# En utilisant Callable.bind().
joueur.hit.connect(_lorsque_joueur_touche.bind("épée", 100))
# Les paramètres ajoutés lors de l'émission du signal sont passés en premier.
joueur.touche.emit("Seigneur des Ténèbres", 5)
# Nous passons deux arguments lors de l'émission (`touche_par`, `niveau`),
# et nous passons deux autres arguments lors de la connexion (`type_arme`, `degats`).
func _lorsque_joueur_touche(touche_par, niveau, type_arme, degats):
print("Touché par %s (niveau %d) avec l'arme %s pour %d dégâts." % [touche_par, niveau, type_arme, degats])
public override void _Ready()
{
// Cela suppose qu'une classe `Joueur` existe, et qui définit un signal `Touche`.
var joueur = new Joueur();
// Utilisation d'expressions lambda qui créent une encapsulation qui capture les paramètres supplémentaires.
// L'expression lambda ne reçoit que les paramètres définis par le délégué du signal.
joueur.Touche += (touchePar, niveau) => LorsqueJoueurTouche(touchePar, niveau, "épée", 100);
// Les paramètres ajoutés lors de l'émission du signal sont passés en premier.
joueur.EmitSignal(SignalName.Touche, "Seigneur des Ténèbres", 5);
}
// Nous passons deux arguments lors de l'émission (`touche_par`, `niveau`),
// et nous passons deux autres arguments lors de la connexion (`type_arme`, `degats`).
private void LorsqueJoueurTouche(string touchePar, int niveau, string typeArme, int degats)
{
GD.Print($"Touché par {touchePar} (niveau {leniveauvel}) avec l'arme {typeArme} for {degats} dégâts.");
}
Note
Il y a des différences notables dans l'utilisation de cette API en C#. Voir Différences de l'API C# par rapport à GDScript pour plus d'informations.
Tutoriels
Constructeurs
Signal() |
|
Signal(object: Object, signal: StringName) |
Méthodes
void |
disconnect(callable: Callable) |
void |
emit(...) vararg const |
get_connections() const |
|
get_name() const |
|
get_object() const |
|
get_object_id() const |
|
has_connections() const |
|
is_connected(callable: Callable) const |
|
is_null() const |
Opérateurs
operator !=(right: Signal) |
|
operator ==(right: Signal) |
Descriptions des constructeurs
Construit un Signal vide sans objet ni nom de signal lié.
Construit un Signal comme une copie du Signal donné.
Signal Signal(object: Object, signal: StringName)
Crée un objet Signal faisant référence à un signal nommé signal dans l'objet object spécifié.
Descriptions des méthodes
int connect(callable: Callable, flags: int = 0) 🔗
Connecte ce signal au callable spécifié. Des drapeaux flags optionnels peuvent aussi être ajoutés pour configurer le comportement de la connexion (voir les constantes ConnectFlags). Vous pouvez fournir des arguments supplémentaires au callable connecté en utilisant Callable.bind().
Un signal ne peut être connecté qu'une fois au même Callable. Si le signal est déjà connecté, cette méthode renvoie @GlobalScope.ERR_INVALID_PARAMETER et génère une erreur, à moins que le signal ne soit connecté à Object.CONNECT_REFERENCE_COUNTED. Pour éviter cela, utilisez d'abord is_connected() pour vérifier les connexions existantes.
for bouton in $Buttons.get_children():
bouton.pressed.connect(_lorsque_appuye.bind(button))
func _lorsque_appuye(button):
print(bouton.name, " a été appuyé")
Note : Si l'objet callable est libéré, la connexion sera perdue.
void disconnect(callable: Callable) 🔗
Déconnecte ce signal du Callable spécifié. Si la connexion n'existe pas, génère une erreur. Utilisez is_connected() pour vous assurer que la connexion existe.
void emit(...) vararg const 🔗
Émet ce signal. Tous les Callable connectés à ce signal seront déclenchés. Cette méthode prend en charge un nombre variable d'arguments, de sorte à ce que les paramètres peuvent être passés en tant que liste séparée par des virgules.
Array get_connections() const 🔗
Renvoie un Array des connexions pour ce signal. Chaque connexion est représentée comme un Dictionary qui contient trois entrées :
signalest une référence à ce signal,callableest une référence au Callable connecté,flagsest une combinaison de drapeaux ConnectFlags.
StringName get_name() const 🔗
Renvoie le nom de ce signal.
Renvoie l'objet émettant ce signal.
Renvoie l'ID de l'objet émettant ce signal (voir Object.get_instance_id()).
bool has_connections() const 🔗
Renvoie true si au moins un Callable est connecté à ce signal.
bool is_connected(callable: Callable) const 🔗
Renvoie true si le Callable spécifié est connecté à ce signal.
Renvoie true si ce Signal n'a pas d'objet et que le nom du signal est vide. Équivalent à signal == Signal().
Descriptions des opérateurs
bool operator !=(right: Signal) 🔗
Renvoie true si les signaux ne partagent pas le même objet ou le même nom.
bool operator ==(right: Signal) 🔗
Renvoie true si les deux signaux partagent le même objet et le même nom.