Un singleton generico
Fa parte della sezione Architettura dei giochi in Unity del percorso Unity di Coddy. Lezione 34 di 50.
Il singleton della sezione 3 è composto da cinque righe che ogni manager ripete: un Instance statico, un Awake che lo imposta, il controllo dei duplicati. Una classe base generica le scrive una volta sola. Ogni manager la estende, indicando il proprio tipo:
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 qualsiasi script
ScoreManager.Instance.Add(10);
SoundManager.Instance.Play("coin");Un membro statico di una classe generica appartiene a ciascun tipo creato a partire da essa: Singleton<ScoreManager> e Singleton<SoundManager> sono due tipi, ciascuno con un proprio Instance, quindi i manager non ne condividono mai uno. ScoreManager.Instance è già tipizzato come ScoreManager, ed è a questo che serve T. All'interno della classe base, this è noto solo come Singleton<T>, quindi this as T lo passa come il manager che è realmente.
La classe base è astratta: Unity inserisce gli oggetti solo nei manager. Un manager che ha bisogno di un proprio Awake non deve scrivere un semplice void Awake(). Questo nasconde il metodo della classe base (il compilatore avvisa di questo), Unity chiama solo quello del manager e Instance non viene mai impostato. Esegui l'override e chiama prima il metodo della classe base:
protected override void Awake()
{
base.Awake();
score = 0;
}Sfida
MedioUna città e una foresta, collegate da portali viola. Ogni scena ha il proprio oggetto Wallet e MusicPlayer, quindi ognuno riproduce la musica per conto proprio e le monete chiamano Wallet.Instance.Add(1). Oggi ogni manager è un singleton della sezione 3, quindi a ogni caricamento il portafoglio viene sostituito con uno vuoto. Dai a entrambi i manager una classe base generica che li mantenga durante i caricamenti delle scene:
- In
PersistentSingleton.cs, scrivipublic abstract class PersistentSingleton<T>, un MonoBehaviour per qualsiasi tipo T che sia un MonoBehaviour, con unInstancestatico pubblico di tipo T che può essere impostato solo dalla classe e unprotected virtual void Awake(). - Il suo Awake mantiene la prima istanza del suo tipo: diventa Instance e sopravvive ai caricamenti delle scene. Qualsiasi istanza successiva distrugge il proprio oggetto e non modifica nulla.
WalleteMusicPlayerereditano da essa, e i rispettivi campiInstancevanno rimossi.MusicPlayermantiene un proprio Awake che registraNow playing: Adventure. Deve essere eseguito dopo l'Awake della classe base, e solo per l'istanza che rimane, così la musica parte una volta per partita.
Le frecce fanno camminare il Player. Premi Play, raccogli la moneta, vai nella foresta e torna indietro, poi premi Check.
Provalo tu
using UnityEngine;
// PersistentSingleton<T>: un'unica istanza che persiste durante i caricamenti delle scene
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Architettura dei giochi in Unity
1Componenti, non gerarchie
Componenti piccoliUno script base per i nemiciComponenti astrattiComponenti che collaboranoRiepilogo: torretta modulare4Dati serializzati
Classi serializzabiliListe nell'InspectorEnum nell'InspectorRiepilogo: tabella del bottino7Macchine a stati
Gli stati come classiUna macchina a statiTransizioniIntelligenze dei nemiciRiepilogo: stati della porta10Progetto: Sopravvissuto nell’arena
L’eroeTipi di nemici5ScriptableObjects
Asset di datiStatistiche delle armiImpostazioni condiviseOndate come datiRiepilogo: database degli oggetti8Codice riutilizzabile
Metodi di estensioneUn singleton genericoFunzioni di supporto genericheRipasso: FindNearest