Menu
CoddyTech

In OnEnable abonnieren

Teil des Abschnitts Spielarchitektur in Unity der Unity-Journey von Coddy. Lektion 11 von 50.

Ein Listener, der zerstört wird, verlässt das Ereignis nicht von selbst. Das Ereignis hält seine Methode weiterhin fest, und der nächste Invoke ruft sie auf der zerstörten Komponente auf. Die erste Verwendung von transform in dieser Methode löst eine MissingReferenceException aus, und da eine Ausnahme den Invoke beendet, werden auch die Listener danach übersprungen. Daher braucht jedes += ein -=, und Unitys Methodenpaar dafür ist OnEnable und 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 ruft OnDisable auf, wenn das Objekt mit SetActive(false) ausgeschaltet wird, wenn das Skript deaktiviert wird und wenn das Objekt zerstört wird, und zwar vor OnDestroy. OnEnable wird jedes Mal ausgeführt, wenn es wieder eingeschaltet wird. Mit diesem Methodenpaar lauscht ein Wächter genau so lange, wie er aktiv ist: Ein zerstörter Wächter ist aus dem Ereignis entfernt, ein für eine Zwischensequenz ausgeschalteter Wächter ignoriert den Alarm, und sobald er wieder eingeschaltet wird, lauscht er erneut.

Zwei andere Kombinationen funktionieren nicht richtig. Bei += in Start und -= in OnDisable lauscht ein aus- und wieder eingeschalteter Wächter nie wieder, weil Start nur einmal ausgeführt wird. Bei += in OnEnable und ohne -= fügt jede Rückkehr RunTo erneut hinzu, und ein Alarm ruft die Methode zweimal auf. Das Entfernen einer Methode, die nicht abonniert ist, bewirkt nichts, daher muss -= in OnDisable nie überprüft werden.

challenge icon

Aufgabe

Einfach

Die Dorfglocke läutet jedes Mal, wenn du die Leertaste drückst (Bell.cs, bereit), und ihr Ereignis OnRing benachrichtigt die Dorfbewohner. Ein Dorfbewohner hüpft bei jedem Läuten und geht nach ringsToLeave Läuten nach Hause: Hop zerstört ihn. Ana geht nach 2 Läuten nach Hause. Läute ein drittes Mal, und in der Konsole wird eine MissingReferenceException angezeigt.

Behebe Villager.cs, sodass ein Dorfbewohner genau dann auf die Glocke hört, wenn er aktiv ist:

  • Abonniere Hop jedes Mal, wenn der Dorfbewohner aktiviert wird, für das Ereignis der Glocke, und melde ihn ab, wenn der Dorfbewohner deaktiviert oder zerstört wird. Lass Hop und Update unverändert.
  • Ein mit SetActive(false) deaktivierter Dorfbewohner hüpft nicht. Wird er wieder aktiviert, hüpft er bei jedem Läuten einmal.

Drücke Play, läute die Glocke viermal und beobachte die Konsole, dann Check.

Probier es selbst

using UnityEngine;

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

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

    void Update()
    {
        // nach einem Hüpfer wieder auf den Boden fallen
        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 iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Spielarchitektur in Unity