Subskrypcja w OnEnable
Część sekcji Architektura gier w Unity ścieżki Unity w Coddy. Lekcja 11 z 50.
Słuchacz, który zostanie zniszczony, sam nie opuszcza zdarzenia. Zdarzenie nadal przechowuje jego metodę, a następne wywołanie Invoke wywołuje ją na zniszczonym komponencie. Pierwsze użycie transform w tej metodzie powoduje wyjątek MissingReferenceException, a ponieważ wyjątek kończy Invoke, pomijani są również kolejni słuchacze. Dlatego każdemu += musi odpowiadać -=, a para metod Unity do tego celu to OnEnable i 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 wywołuje OnDisable, gdy obiekt zostanie wyłączony za pomocą SetActive(false), gdy skrypt zostanie wyłączony oraz gdy obiekt zostanie zniszczony, przed OnDestroy. OnEnable jest uruchamiane za każdym razem, gdy obiekt zostaje ponownie włączony. Dzięki tej parze strażnik nasłuchuje dokładnie wtedy, gdy jest aktywny: zniszczony strażnik znika ze zdarzenia, strażnik wyłączony na potrzeby przerywnika filmowego ignoruje alarm, a po ponownym włączeniu znów nasłuchuje.
Dwie inne kombinacje nie działają poprawnie. Gdy += znajduje się w Start, a -= w OnDisable, strażnik wyłączony i ponownie włączony już nie nasłuchuje, ponieważ Start jest uruchamiane tylko raz. Gdy += znajduje się w OnEnable, a brakuje -=, każde ponowne włączenie dodaje RunTo jeszcze raz, więc jedno wywołanie alarmu uruchamia ją dwukrotnie. Usunięcie metody, która nie jest subskrybowana, nic nie robi, więc w OnDisable nigdy nie trzeba sprawdzać, czy wykonać -=.
Wyzwanie
ŁatwyDzwon w wiosce dzwoni za każdym razem, gdy naciskasz Spację (Bell.cs, gotowe), a jego zdarzenie OnRing informuje mieszkańców wioski. Mieszkaniec podskakuje przy każdym dzwonku i wraca do domu po ringsToLeave dzwonkach: Hop go niszczy. Ana wraca do domu po 2 dzwonkach. Zadzwoń po raz trzeci, a w konsoli pojawi się MissingReferenceException.
Napraw Villager.cs, aby mieszkaniec nasłuchiwał dzwonka dokładnie wtedy, gdy jest aktywny:
- Za każdym razem, gdy mieszkaniec zostaje włączony, zasubskrybuj zdarzenie dzwonka metodą
Hop, a gdy mieszkaniec zostaje wyłączony lub zniszczony — anuluj subskrypcję. PozostawHopiUpdatebez zmian. - Mieszkaniec wyłączony za pomocą
SetActive(false)nie podskakuje. Po ponownym włączeniu podskakuje raz przy każdym dzwonku.
Naciśnij Play, zadzwoń cztery razy i obserwuj konsolę, a następnie naciśnij Check.
Spróbuj swoich sił
using UnityEngine;
public class Villager : MonoBehaviour
{
public Bell bell;
public int ringsToLeave = 3;
public int hops;
void Start()
{
bell.OnRing += Hop;
}
void Update()
{
// opadnij z powrotem na ziemię po podskoku
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);
}
}
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Architektura gier w Unity
1Komponenty, nie hierarchie
Małe komponentyPodstawowy skrypt przeciwnikaKomponenty abstrakcyjneWspółpracujące komponentyPodsumowanie: modułowa wieżyczka4Dane serializowane
Klasy serializowalneListy w InspectorzeWyliczenia w InspectorzePodsumowanie: tabela łupów10Projekt: Arena przetrwania
BohaterTypy wrogów2Interfejsy w Unity
IDamageableInterfejsy i TryGetComponentGetComponentsPodsumowanie: klawisz interakcji5ScriptableObjects
Zasoby danychStatystyki broniWspółdzielone ustawieniaFale jako danePowtórka: baza danych przedmiotów8Kod wielokrotnego użytku
Metody rozszerzająceGeneryczny singletonGeneryczne metody pomocniczePodsumowanie: FindNearest3Zdarzenia
Zdarzenia C# w UnitySubskrypcja w OnEnablePola UnityEventZdarzenia sterują interfejsemPodsumowanie: wyskakujące okno osiągnięcia6Zapisywanie za pomocą JSON
JsonUtilityZapisz gręWczytywanie i wartości domyślnePowtórka: sloty zapisu