Generyczny singleton
Część sekcji Architektura gier w Unity ścieżki Unity w Coddy. Lekcja 34 z 50.
Singleton z sekcji 3 to pięć wierszy, które powtarza każdy menedżer: statyczne Instance, Awake, które je ustawia, i sprawdzenie duplikatów. Generyczna klasa bazowa zapisuje je raz. Każdy menedżer dziedziczy po niej, podając własny typ:
public abstract class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
public static T Instance { get; private set; }
protected virtual void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(gameObject);
return;
}
Instance = this as T;
}
}
public class ScoreManager : Singleton<ScoreManager>
{
public int score;
public void Add(int points) { score += points; }
}
public class SoundManager : Singleton<SoundManager>
{
public void Play(string clip) { Debug.Log("Playing " + clip); }
}// w dowolnym skrypcie
ScoreManager.Instance.Add(10);
SoundManager.Instance.Play("coin");Składowa statyczna klasy generycznej należy do każdego utworzonego z niej typu: Singleton<ScoreManager> i Singleton<SoundManager> to dwa typy, z których każdy ma własne Instance, więc menedżery nigdy go nie współdzielą. ScoreManager.Instance ma już typ ScoreManager — właśnie do tego służy T. W klasie bazowej this jest znane tylko jako Singleton<T>, więc this as T przekazuje je jako typ menedżera, którym rzeczywiście jest.
Klasa bazowa jest abstrakcyjna: Unity umieszcza na obiektach tylko menedżery. Menedżer, który potrzebuje własnego Awake, nie może napisać zwykłego void Awake(). Ukrywa to metodę klasy bazowej (kompilator wyświetli ostrzeżenie), Unity wywoła tylko metodę menedżera, a Instance nigdy nie zostanie ustawione. Zastosuj override i najpierw wywołaj metodę klasy bazowej:
protected override void Awake()
{
base.Awake();
score = 0;
}Wyzwanie
ŚredniMiasteczko i las połączone fioletowymi portalami. Każda scena ma własne obiekty Wallet i MusicPlayer, więc każdy z nich odtwarza muzykę niezależnie, a monety wywołują Wallet.Instance.Add(1). Dziś każdy menedżer jest singletonem z sekcji 3, więc każde wczytanie zastępuje portfel pustym. Utwórz dla obu menedżerów klasę bazową generyczną, która zachowa je podczas wczytywania scen:
- W pliku
PersistentSingleton.csnapiszpublic abstract class PersistentSingleton<T>, klasę MonoBehaviour dla dowolnego typu MonoBehaviour T, z publicznym statycznym polemInstancetypu T, którego wartość może ustawiać tylko ta klasa, oraz metodąprotected virtual void Awake(). - Metoda Awake zachowuje pierwszy obiekt tego rodzaju: staje się on Instance i przetrwa wczytywanie scen. Każdy kolejny niszczy własny obiekt i niczego nie zmienia.
WalletiMusicPlayerdziedziczą po tej klasie, a ich własne polaInstancenależy usunąć.MusicPlayerzachowuje własną metodę Awake, która rejestrujeNow playing: Adventure. Musi ona uruchomić się po metodzie Awake klasy bazowej i tylko dla obiektu, który pozostaje, aby muzyka zaczynała grać raz na grę.
Strzałki poruszają Playerem. Naciśnij Play, zbierz monetę, przejdź do lasu i wróć, a następnie naciśnij Check.
Spróbuj swoich sił
using UnityEngine;
// PersistentSingleton<T>: jedna instancja, która pozostaje aktywna podczas wczytywania kolejnych scen
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: FindNearest