Menu
CoddyTech

Iscrizione in OnEnable

Fa parte della sezione Architettura dei giochi in Unity del percorso Unity di Coddy. Lezione 13 di 64.

Un listener che viene distrutto non lascia l'evento da solo. L'evento conserva ancora il suo metodo e il successivo Invoke lo chiama sul componente distrutto. Il primo utilizzo di transform in quel metodo genera una MissingReferenceException e, poiché un'eccezione interrompe Invoke, anche i listener successivi vengono ignorati. Quindi a ogni += deve corrispondere un -=, e la coppia di metodi di Unity per farlo è OnEnable e 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 chiama OnDisable quando l'oggetto viene disattivato con SetActive(false), quando lo script viene disabilitato e quando l'oggetto viene distrutto, prima di OnDestroy. OnEnable viene eseguito ogni volta che viene riattivato. Con questa coppia, una guardia ascolta esattamente mentre è attiva: una guardia distrutta viene rimossa dall'evento, una guardia disattivata per una scena cinematografica ignora l'allarme e, una volta riattivata, torna ad ascoltare.

Altre due combinazioni non funzionano. Con += in Start e -= in OnDisable, una guardia disattivata e poi riattivata non ascolta più, perché Start viene eseguito una sola volta. Con += in OnEnable e senza -=, ogni riattivazione aggiunge di nuovo RunTo e un allarme lo chiama due volte. Rimuovere un metodo a cui non si è iscritti non fa nulla, quindi in OnDisable non è mai necessario verificare prima di usare -=.

challenge icon

Sfida

Facile

Fai in modo che ogni abitante del villaggio ascolti la campana solo mentre è attivo.

  1. In Villager.cs, sposta bell.OnRing += Hop; da Start() a un nuovo void OnEnable() ed elimina Start().
  2. Aggiungi void OnDisable() con bell.OnRing -= Hop;. «Verifica» disattiva e riattiva Cleo per testare questa funzionalità.

Premi «Gioca» e suona la campana quattro volte: Ana torna a casa dopo il secondo rintocco e non compare alcun errore. Poi premi «Verifica».

Provalo tu

using UnityEngine;

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

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

    void Update()
    {
        // ricadi a terra dopo un salto
        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);
        }
    }
}

Tutte le lezioni di Architettura dei giochi in Unity

Esercitati da solo: Playground Unity