Menu
CoddyTech

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;
}
challenge icon

Sfida

Medio

Una 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, scrivi public abstract class PersistentSingleton<T>, un MonoBehaviour per qualsiasi tipo T che sia un MonoBehaviour, con un Instance statico pubblico di tipo T che può essere impostato solo dalla classe e un protected 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.
  • Wallet e MusicPlayer ereditano da essa, e i rispettivi campi Instance vanno rimossi.
  • MusicPlayer mantiene un proprio Awake che registra Now 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
quiz iconMettiti alla prova

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