Un singleton generico
Fa parte della sezione Architettura dei giochi in Unity del percorso Unity di Coddy. Lezione 43 di 64.
Il singleton della sezione 3 consiste in cinque righe che ogni gestore ripete: un Instance statico, un Awake che lo imposta, il controllo dei duplicati. Una classe base generica le scrive una volta sola. Ogni gestore deriva da essa, indicandosi come 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, ognuno con il proprio Instance, quindi i gestori non ne condividono mai uno. ScoreManager.Instance è già tipizzato come ScoreManager, ed è proprio a questo che serve T. All’interno della classe base, this è noto solo come Singleton<T>, quindi this as T lo passa come il gestore che è realmente.
La classe base è astratta: Unity mette sugli oggetti solo i gestori. Un gestore che ha bisogno di un proprio Awake non deve scrivere un semplice void Awake(). Questo nasconde il metodo della classe base (il compilatore avvisa del problema), Unity chiama solo quello del gestore 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
MedioFornisci a entrambi i gestori una base che sopravviva ai caricamenti delle scene.
- In
PersistentSingleton, scriviprotected virtual void Awake(): il primo diventaInstancee resta (DontDestroyOnLoad); uno successivo si autodistrugge. WalleteMusicPlayerderivano da questa classe; elimina il loroInstancee l'Awake di Wallet.MusicPlayeresegue l'override di Awake:base.Awake(), poi, se è l'Instance, registraNow playing: Adventure.
Premi «Gioca», visita la foresta e torna: 1 moneta. Poi premi «Verifica».
Provalo tu
using UnityEngine;
public abstract class PersistentSingleton<T> : MonoBehaviour where T : MonoBehaviour
{
public static T Instance { get; private set; }
// Awake: mantieni il primo durante i caricamenti delle scene, distruggi tutti quelli successivi
}
Tutte le lezioni di Architettura dei giochi in Unity
1Componenti, non gerarchie
Componenti piccoliUno script base per i nemiciComponenti astrattiComponenti che collaboranoRipasso: torretta modulareRipasso: cannone doppio4Dati serializzati
Classi serializzabiliElenchi nell'InspectorEnum nell'InspectorRiepilogo: tabella del bottinoRiepilogo: tira il bottino2Interfacce in Unity
IDamageableInterfacce e TryGetComponentGetComponentsRiepilogo: tasto InteragisciRiepilogo: il più vicino a portata5ScriptableObjects
Asset di datiStatistiche delle armiImpostazioni condiviseSalva il ventoOnde come datiRiepilogo: database degli oggettiRiepilogo: comprare dal negozio8Codice riutilizzabile
Metodi di estensioneUn singleton genericoFunzioni di supporto genericheRipasso: FindNearestEsercitati da solo: Playground Unity