Mantenere i dati tra le scene
Fa parte della sezione Creare veri giochi del percorso Unity di Coddy. Lezione 20 di 60.
Il caricamento di una scena distrugge ogni oggetto della scena precedente, ma alcune cose devono durare per tutta la partita, come le monete che un giocatore porta da un livello all'altro. DontDestroyOnLoad(gameObject) sposta un oggetto fuori dalla sua scena e lo inserisce in una scena tutta sua, chiamata DontDestroyOnLoad nella Hierarchy quando si preme «Gioca», che i caricamenti non toccano mai. Funziona solo su un oggetto radice: su un oggetto figlio, Unity registra un avviso e non conserva nulla. Gli oggetti figli dell'oggetto conservato vengono mantenuti, ma non gli oggetti a cui punta: dopo il caricamento, un campo che puntava a un oggetto della vecchia scena contiene un oggetto distrutto, che risulta uguale a null.
public class GameSession : MonoBehaviour
{
public static GameSession Instance;
public int coins;
void Awake()
{
if (Instance != null)
{
Destroy(gameObject);
return;
}
Instance = this;
DontDestroyOnLoad(gameObject);
}
}Questa GameSession si trova nella scena Menu. Si passa da Menu a Level1 e poi si torna a Menu, che ricrea tutti i suoi oggetti, compresa una nuova GameSession, mentre quella conservata è ancora presente. Senza il controllo in Awake ce ne sarebbero due e la nuova sostituirebbe Instance con 0 monete. Con il controllo, la nuova trova Instance già impostata, distrugge sé stessa e si ferma, mentre la sessione che ha attraversato i livelli rimane.
return è importante perché Destroy attende la fine del frame. Senza, il resto di Awake verrebbe comunque eseguito per la nuova istanza: Instance = this; farebbe puntare ogni script a un oggetto sul punto di essere distrutto.
Sfida
FacileMantieni attivo un unico cronometro della partita durante il caricamento di ogni scena.
- In
Awake(), seInstance != null, chiamaDestroy(gameObject);ereturn;. Altrimenti impostaInstancee chiamaDontDestroyOnLoad(gameObject);. - Il caricamento distrugge il testo del vecchio livello, quindi in
Update(), prima della riga del testo, quandoclockText == null, impostaclockText = GameObject.Find("ClockText").GetComponent<TMP_Text>();.
Premi «Gioca», vai a Level2 e torna indietro: un solo cronometro continua a contare. Poi premi «Verifica».
Provalo tu
using UnityEngine;
using TMPro;
public class RunClock : MonoBehaviour
{
public static RunClock Instance;
public TMP_Text clockText;
private float seconds;
void Awake()
{
Instance = this;
}
void Update()
{
seconds += Time.deltaTime;
clockText.text = "Time: " + seconds.ToString("0.0");
}
public void Split()
{
Debug.Log("Split: " + seconds.ToString("0.0"));
}
}
Tutte le lezioni di Creare veri giochi
1Testo sullo schermo
Canvas e testoMostra il punteggioFormattare i numeriUn timer per il conto alla rovesciaRiepilogo: tachimetro4Scene e livelli
Caricare una scenaRiavviare il livelloLivello successivoMantenere i dati tra le sceneRiepilogo: selezione del livello2Pulsanti e schermate
Pulsanti e onClickLambdaCollegare nell'InspectorPannelli attivi e disattiviBarre della saluteRiepilogo: negozio degli upgrade5Salvare con PlayerPrefs
Salvare un numeroCaricare con un valore predefinitoPunteggio massimoSalvare le impostazioniRiepilogo: monete in banca8Controller del personaggio
CharacterController.MoveGravità manualeSaltoSpingere gli oggettiMuoviti dove guardiRiepilogo: doppio salto3Il gestore del gioco
Uno script gestisce il giocoIl SingletonStati di giocoSelezionare lo statoRiepilogo: gestore del round6Progetto: Runner infinito
Tre corsieOstacoli in arrivo9Il nuovo sistema di input
Due sistemi di inputTastiera e mousePremuto in questo frameAzioni di inputRiepilogo: cambio di inputEsercitati da solo: Playground Unity