Menu
CoddyTech

S’abonner dans OnEnable

Fait partie de la section Architecture de jeu dans Unity du Journey Unity de Coddy. Leçon 11 sur 50.

Un écouteur qui est détruit ne se désabonne pas de l’événement de lui-même. L’événement conserve sa méthode, et le prochain Invoke l’appelle sur le composant détruit. La première utilisation de transform dans cette méthode déclenche une MissingReferenceException et, comme une exception interrompt Invoke, les écouteurs suivants sont également ignorés. Ainsi, chaque += doit avoir un -=, et Unity fournit une paire de méthodes pour cela : OnEnable et OnDisable :

public class Guard : MonoBehaviour
{
    public Alarm alarm;

    void OnEnable()
    {
        alarm.OnTriggered += RunTo;
    }

    void OnDisable()
    {
        alarm.OnTriggered -= RunTo;
    }

    void RunTo(Vector3 spot)
    {
        transform.LookAt(spot);
    }
}

Unity appelle OnDisable lorsque l’objet est désactivé avec SetActive(false), lorsque le script est désactivé et lorsque l’objet est détruit, avant OnDestroy. OnEnable s’exécute chaque fois qu’il est réactivé. Avec cette paire, un garde écoute exactement tant qu’il est actif : un garde détruit est retiré de l’événement, un garde désactivé pour une cinématique ignore l’alarme et, une fois réactivé, il écoute de nouveau.

Deux autres associations posent problème. Avec += dans Start et -= dans OnDisable, un garde désactivé puis réactivé n’écoute plus jamais, car Start ne s’exécute qu’une seule fois. Avec += dans OnEnable et sans -=, chaque réactivation ajoute de nouveau RunTo, et une alarme l’appelle deux fois. Retirer une méthode qui n’est pas abonnée ne fait rien ; il n’est donc jamais nécessaire de vérifier avant d’utiliser -= dans OnDisable.

challenge icon

Défi

Facile

La cloche du village sonne chaque fois que tu appuies sur Espace (Bell.cs, déjà prêt), et son événement OnRing avertit les villageois. Un villageois fait un bond à chaque sonnerie et rentre chez lui après ringsToLeave sonneries : Hop le détruit. Ana rentre chez elle après 2 sonneries. Sonne une troisième fois et la Console affiche une MissingReferenceException.

Corrige Villager.cs pour qu’un villageois écoute la cloche uniquement lorsqu’il est actif :

  • Abonne Hop à l’événement de la cloche chaque fois que le villageois est activé, et désabonne-le lorsque le villageois est désactivé ou détruit. Garde Hop et Update tels quels.
  • Un villageois désactivé avec SetActive(false) ne fait pas de bond. Réactivé, il fait un bond à chaque sonnerie.

Appuie sur Play, sonne quatre fois et observe la Console, puis Check.

Essayez vous-même

using UnityEngine;

public class Villager : MonoBehaviour
{
    public Bell bell;
    public int ringsToLeave = 3;
    public int hops;

    void Start()
    {
        bell.OnRing += Hop;
    }

    void Update()
    {
        // retomber au sol après un saut
        Vector3 p = transform.position;
        transform.position = new Vector3(p.x, Mathf.MoveTowards(p.y, 0.5f, 4f * Time.deltaTime), p.z);
    }

    void Hop(int ring)
    {
        hops++;
        transform.position += Vector3.up * 0.8f;
        if (hops == ringsToLeave)
        {
            Debug.Log(name + " goes home");
            Destroy(gameObject);
        }
    }
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Architecture de jeu dans Unity