Signaux

Introduction

Les signaux sont la version de Godot du modèle observer. Ils permettent à un nœud d’envoyer un message que les autres nœuds peuvent écouter et auquel ils peuvent répondre. Par exemple, au lieu de vérifier en continu si un bouton est appuyé, le bouton peut émettre un signal lorsqu’il est appuyé.

Note

Vous pouvez en savoir plus sur le modèle d’observateur ici : http://gameprogrammingpatterns.com/observer.html

Les signaux sont un moyen de rendre vos objets de jeu indépendants, ce qui conduit à un code mieux organisé et plus facile à gérer. Au lieu de forcer les objets du jeu à s’attendre à ce que d’autres objets soient toujours présents, ils peuvent émettre des signaux auxquels tout objet intéressé peut s’abonner et répondre.

Vous trouverez ci-dessous quelques exemples d’utilisation des signaux dans vos propres projets.

Exemple de minuterie

Pour voir comment fonctionnent les signaux, essayons d’utiliser un nœud Timer. Créez une nouvelle scène avec un nœud et deux enfants : un Timer et un Sprite. Dans le dock scène, renommez Node en TimerExample.

Pour la texture du Sprite, vous pouvez utiliser l’icône Godot, ou toute autre image que vous souhaitez. Pour ce faire, sélectionnez Load dans le menu déroulant de l’attribut Texture du Sprite. Attachez un script au nœud racine, mais n’y ajoutez pas encore de code.

L’arbre de la scène devrait ressembler à ceci :

../../_images/signals_node_setup.png

Dans les propriétés du nœud Timer, cochez la case « On » à côté de Autostart. Le Timer démarrera automatiquement lorsque vous exécuterez la scène. Vous pouvez laisser le Wait Time (temps d’attente) à 1 seconde.

À côté de l’onglet « Inspecteur » se trouve un onglet intitulé « Nœud ». Cliquez sur cet onglet et vous verrez tous les signaux que le nœud sélectionné peut émettre. Dans le cas du nœud Timer, celui qui nous intéresse est « timeout ». Ce signal est émis chaque fois que la minuterie atteint 0.

../../_images/signals_node_tab_timer.png

Cliquez sur le signal « timeout() » et cliquez sur « Connecter… ». Vous verrez la fenêtre suivante dans laquelle vous pouvez définir comment vous voulez connecter le signal :

../../_images/signals_connect_dialog_timer.png

Sur le côté gauche, vous verrez les nœuds de votre scène et pourrez sélectionner le nœud que vous souhaitez « écouter » pour le signal. Notez que le nœud Timer est rouge - ce n’est pas une erreur, mais une indication visuelle que c’est le nœud qui émet le signal. Sélectionnez le nœud racine.

Avertissement

Le nœud cible doit être associé à un script ou vous recevrez un message d’erreur.

Au bas de la fenêtre se trouve un champ intitulé « Méthode en Noeud ». Il s’agit du nom de la fonction que vous souhaitez utiliser dans le script du nœud cible. Par défaut, Godot créera cette fonction en utilisant la convention de dénomination _on_<nom_nœud>_<nom_signal> mais vous pouvez la modifier si vous le souhaitez.

Cliquez sur « Connecter » et vous verrez que la fonction a été créée dans le script :

extends Node

func _on_Timer_timeout():
    pass # replace with function body
public class TimerExample : Node
{
    private void _on_Timer_timeout()
    {
        // Replace with function body.
    }
}

Nous pouvons maintenant remplacer le code de l’espace réservé par le code que nous souhaitons exécuter à la réception du signal. Faisons clignoter le Sprite :

extends Node

func _on_Timer_timeout():
    # Note: the `$` operator is a shorthand for `get_node()`,
    # so `$Sprite` is equivalent to `get_node("Sprite")`.
    $Sprite.visible = !$Sprite.visible
public class TimerExample : Node
{
    public void _on_Timer_timeout()
    {
        var sprite = GetNode<Sprite>("Sprite");
        sprite.Visible = !sprite.Visible;
    }
}

Exécutez la scène et vous verrez le Sprite clignoter à chaque seconde. Vous pouvez modifier la propriété Temps d’Attente du temporisateur pour modifier cela.

Connecter des signaux dans le code

Vous pouvez également établir la connexion du signal en code plutôt qu’avec l’éditeur. Cela est généralement nécessaire lorsque vous installez des nœuds via du code et vous ne pouvez donc pas utiliser l’éditeur pour établir la connexion.

Commencez par déconnecter le signal en sélectionnant la connexion dans l’onglet « Nœud » de la minuterie et en cliquant sur Déconnecter.

../../_images/signals_disconnect_timer.png

Pour établir la connexion en code, nous pouvons utiliser la fonction connect. Nous allons la mettre dans _ready() afin que la connexion soit établie lors de l’exécution. La syntaxe de la fonction est <nœud_source>.connecter(<nom_signal>, <nœud_cible>, <nom_fonction_ cible>). Voici le code pour la connexion de notre minuterie :

extends Node

func _ready():
    $Timer.connect("timeout", self, "_on_Timer_timeout")

func _on_Timer_timeout():
    $Sprite.visible = !$Sprite.visible
public class TimerExample : Node
{
    public override void _Ready()
    {
        GetNode("Timer").Connect("timeout", this, nameof(_on_Timer_timeout));
    }

    public void _on_Timer_timeout()
    {
        var sprite = GetNode<Sprite>("Sprite");
        sprite.Visible = !sprite.Visible;
    }
}

Signaux personnalisés

Vous pouvez également déclarer vos propres signaux personnalisés dans Godot :

extends Node

signal my_signal
public class Main : Node
{
    [Signal]
    public delegate void MySignal();
}

Une fois déclarés, vos signaux personnalisés apparaîtront dans l’inspecteur et pourront être connectés de la même manière que les signaux intégrés d’un nœud.

Pour émettre un signal par le code, utilisez la fonction emit_signal :

extends Node

signal my_signal

func _ready():
    emit_signal("my_signal")
public class Main : Node
{
    [Signal]
    public delegate void MySignal();

    public override void _Ready()
    {
        EmitSignal(nameof(MySignal));
    }
}

Conclusion

De nombreux types de nœuds intégrés de Godot fournissent des signaux que vous pouvez utiliser pour détecter des événements. Par exemple, un Area2D représentant une pièce de monnaie émet un signal body_entered chaque fois que le corps physique du joueur entre en collision avec, ce qui vous permet de savoir quand le joueur la récupère.

Dans la section suivante Votre premier jeu, vous construirez un jeu complet comprenant plusieurs utilisations de signaux pour connecter différents composants du jeu.