Ein generisches Singleton
Teil des Abschnitts Spielarchitektur in Unity der Unity-Journey von Coddy. Lektion 43 von 64.
Der Singleton aus Abschnitt 3 besteht aus fünf Zeilen, die jeder Manager wiederholt: eine statische Instance, ein Awake, das sie festlegt, und die Prüfung auf Duplikate. Eine generische Basisklasse schreibt sie einmal. Jeder Manager leitet sich davon ab und gibt seinen eigenen Typ an:
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); }
}// in jedem Skript
ScoreManager.Instance.Add(10);
SoundManager.Instance.Play("coin");Ein statisches Mitglied einer generischen Klasse gehört zu jedem daraus erzeugten Typ: Singleton<ScoreManager> und Singleton<SoundManager> sind zwei Typen mit jeweils einer Instance, daher teilen sich die Manager niemals eine. ScoreManager.Instance ist bereits als ScoreManager typisiert – genau dafür gibt es T. Innerhalb der Basisklasse ist this nur als Singleton<T> bekannt, daher übergibt this as T es als den Manager, der es tatsächlich ist.
Die Basisklasse ist abstrakt: Unity setzt nur die Manager auf Objekte. Ein Manager, der ein eigenes Awake benötigt, darf kein einfaches void Awake() schreiben. Dadurch wird die Methode der Basisklasse ausgeblendet (der Compiler warnt davor), Unity ruft nur die Methode des Managers auf und Instance wird nie festgelegt. Überschreibe die Methode und rufe zuerst die Basisklassenmethode auf:
protected override void Awake()
{
base.Awake();
score = 0;
}Aufgabe
MittelGib beiden Managern eine Basis, die Szenenwechsel übersteht.
- Schreibe in
PersistentSingletonprotected virtual void Awake(): Das erste Objekt wird zuInstanceund bleibt erhalten (DontDestroyOnLoad); ein späteres zerstört sich selbst. WalletundMusicPlayerleiten davon ab; lösche ihreInstanceund das Awake von Wallet.MusicPlayerüberschreibt Awake:base.Awake(), dann wird, falls es die Instance ist,Now playing: Adventureprotokolliert.
Drücke „Spielen“, besuche den Wald und kehre zurück: 1 Münze. Drücke dann „Prüfen“.
Probier es selbst
using UnityEngine;
public abstract class PersistentSingleton<T> : MonoBehaviour where T : MonoBehaviour
{
public static T Instance { get; private set; }
// Awake: Die erste Instanz über Szenenwechsel hinweg beibehalten, jede spätere zerstören
}
Alle Lektionen in Spielarchitektur in Unity
1Komponenten statt Hierarchien
Kleine KomponentenEin Basis-GegnerskriptAbstrakte KomponentenZusammenwirkende KomponentenRückblick: Modulares GeschützRückblick: Zwillingskanone4Serialisierte Daten
Serialisierbare KlassenListen im InspectorEnums im InspectorRückblick: Loot-TabelleRückblick: Beute auswürfeln2Schnittstellen in Unity
IDamageableSchnittstellen und TryGetComponentGetComponentsZusammenfassung: InteraktionstasteZusammenfassung: Nächstes in Reichweite5ScriptableObjects
Daten-AssetsWaffenwerteGemeinsame EinstellungenDen Wind speichernWellen als DatenRückblick: Item-DatenbankRückblick: Im Shop einkaufen8Wiederverwendbarer Code
ErweiterungsmethodenEin generisches SingletonGenerische HilfsmethodenRückblick: FindNearestÜbe selbstständig: Unity-Playground