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 -=.
Sfida
FacileFai in modo che ogni abitante del villaggio ascolti la campana solo mentre è attivo.
- In
Villager.cs, spostabell.OnRing += Hop;daStart()a un nuovovoid OnEnable()ed eliminaStart(). - Aggiungi
void OnDisable()conbell.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
1Componenti, non gerarchie
Componenti piccoliUno script base per i nemiciComponenti astrattiComponenti che collaboranoRipasso: torretta modulareRipasso: cannone doppio4Dati serializzati
Classi serializzabiliElenchi nell'InspectorEnum nell'InspectorRiepilogo: tabella del bottinoRiepilogo: tira il bottino2Interfacce in Unity
IDamageableInterfacce e TryGetComponentGetComponentsRiepilogo: tasto InteragisciRiepilogo: il più vicino a portata5ScriptableObjects
Asset di datiStatistiche delle armiImpostazioni condiviseSalva il ventoOnde come datiRiepilogo: database degli oggettiRiepilogo: comprare dal negozioEsercitati da solo: Playground Unity