Subskrybuj w OnEnable
Część sekcji Architektura gier w Unity ścieżki Unity w Coddy. Lekcja 13 z 64.
Zniszczony nasłuchujący nie opuszcza zdarzenia sam z siebie. Zdarzenie nadal przechowuje jego metodę, a następne wywołanie Invoke uruchamia ją na zniszczonym komponencie. Pierwsze użycie transform w tej metodzie powoduje wyjątek MissingReferenceException, a ponieważ wyjątek przerywa Invoke, pomijani są również kolejni nasłuchujący. Dlatego każde += wymaga -=, 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 zostaje wyłączony za pomocą SetActive(false), gdy skrypt zostaje wyłączony oraz gdy obiekt zostaje zniszczony — przed OnDestroy. OnEnable uruchamia się 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 są błędne. Jeśli użyjesz += w Start i -= w OnDisable, strażnik wyłączony i ponownie włączony już nie nasłuchuje, ponieważ Start uruchamia się tylko raz. Jeśli użyjesz += w OnEnable i nie dodasz -=, za każdym razem po ponownym włączeniu RunTo zostanie dodane ponownie, więc jeden alarm wywoła tę metodę dwa razy. Usunięcie metody, która nie jest subskrybowana, nic nie robi, dlatego -= w OnDisable nigdy nie wymaga sprawdzenia.
Wyzwanie
ŁatwySpraw, by każdy mieszkaniec wioski nasłuchiwał dzwonka tylko wtedy, gdy jest aktywny.
- W pliku
Villager.csprzenieśbell.OnRing += Hop;zStart()do nowej metodyvoid OnEnable()i usuńStart(). - Dodaj metodę
void OnDisable()zbell.OnRing -= Hop;. „Sprawdź” przełącza Cleo, aby ją przetestować.
Naciśnij „Graj” i zadzwoń cztery razy: Ana wraca do domu po drugim dzwonku, a żaden błąd się nie pojawia. Następnie naciśnij „Sprawdź”.
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);
}
}
}
Wszystkie lekcje w sekcji Architektura gier w Unity
1Komponenty, nie hierarchie
Małe komponentyBazowy skrypt przeciwnikaKomponenty abstrakcyjneWspółpracujące komponentyPowtórka: modułowa wieżyczkaPowtórka: podwójne działo4Dane serializowane
Klasy serializowalneListy w InspectorzeEnumy w InspectorzePodsumowanie: tabela łupówPodsumowanie: losowanie łupów2Interfejsy w Unity
IDamageableInterfejsy i TryGetComponentGetComponentsPowtórka: klawisz interakcjiPowtórka: najbliższy w zasięgu5ScriptableObjects
Zasoby danychStatystyki broniWspółdzielone ustawieniaOcal wiatrFale jako danePowtórka: Baza przedmiotówPowtórka: Kupowanie w sklepie8Kod wielokrotnego użytku
Metody rozszerzająceGeneryczny singletonGeneryczne metody pomocniczePodsumowanie: FindNearest3Zdarzenia
Zdarzenia C# w UnitySubskrybuj w OnEnablePola UnityEventZdarzenia sterują UIPodsumowanie: popup osiągnięciaPodsumowanie: timer popupu6Zapisywanie za pomocą JSON
JsonUtilityZapisz gręWczytywanie i wartości domyślnePodsumowanie: sloty zapisuWybierz i usuń slotPoćwicz samodzielnie: Edytor online Unity