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.
Défi
FacileLa 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. GardeHopetUpdatetels 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);
}
}
}
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
1Des composants, pas des hiérarchies
Des composants simplesUn script de base pour les ennemisDes composants abstraitsDes composants qui fonctionnent ensembleRécapitulatif : tourelle modulaire4Données sérialisées
Classes sérialisablesListes dans l’inspecteurÉnumérations dans l’inspecteurRécapitulatif : table de butin7Machines à états
Les états sous forme de classesUne machine à étatsTransitionsLes cerveaux des ennemisRécapitulatif : états d’une porte10Projet : Survivant de l’arène
Le hérosTypes d’ennemis2Interfaces dans Unity
IDamageableInterfaces et TryGetComponentGetComponentsRécapitulatif : touche d’interaction5ScriptableObjects
Assets de donnéesStatistiques des armesParamètres partagésLes vagues sous forme de donnéesRécapitulatif : base de données d’objets