Menu
CoddyTech

Conserver entre les scènes

Fait partie de la section Créer de vrais jeux du Journey Unity de Coddy. Leçon 20 sur 60.

Le chargement d’une scène détruit tous les objets de l’ancienne, mais certaines choses doivent durer pendant toute la partie, comme les pièces qu’un joueur emporte d’un niveau à l’autre. DontDestroyOnLoad(gameObject) déplace un objet hors de sa scène pour le placer dans une scène à part, appelée DontDestroyOnLoad dans la fenêtre Hierarchy lorsque tu appuies sur « Jouer », que les chargements ne touchent jamais. Cette méthode ne fonctionne que sur un objet racine : sur un objet enfant, Unity affiche un avertissement et ne conserve rien. Les enfants de l’objet conservé sont également conservés, mais pas les objets vers lesquels il ne fait que pointer : après le chargement, un champ qui pointait vers un objet de l’ancienne scène contient un objet détruit, qui est égal à null lors d’une comparaison.

public class GameSession : MonoBehaviour
{
    public static GameSession Instance;
    public int coins;

    void Awake()
    {
        if (Instance != null)
        {
            Destroy(gameObject);
            return;
        }
        Instance = this;
        DontDestroyOnLoad(gameObject);
    }
}

Cette GameSession se trouve dans la scène Menu. Le joueur passe de Menu à Level1, puis revient à Menu, et Menu recrée tous ses objets, y compris une nouvelle GameSession, alors que celle qui a été conservée est toujours là. Sans la vérification dans Awake, il y en aurait deux, et la nouvelle prendrait le relais de Instance avec 0 pièce. Avec cette vérification, la nouvelle trouve Instance déjà définie, se détruit et s’arrête, et la session qui a traversé les niveaux reste en place.

return est important, car Destroy attend la fin de la frame. Sans cela, le reste de Awake s’exécuterait quand même pour la nouvelle instance : Instance = this; ferait pointer tous les scripts vers un objet sur le point d’être détruit.

challenge icon

Défi

Facile

Conservez un seul chronomètre de partie à travers chaque chargement de scène.

  1. Dans Awake(), si Instance != null, appelez Destroy(gameObject); puis return;. Sinon, définissez Instance et appelez DontDestroyOnLoad(gameObject);.
  2. Un chargement détruit le texte de l’ancien niveau. Ainsi, dans Update(), avant la ligne qui définit le texte, lorsque clockText == null, définissez clockText = GameObject.Find("ClockText").GetComponent<TMP_Text>();.

Appuyez sur « Jouer », allez au niveau 2 puis revenez : un seul chronomètre continue de compter. Ensuite, appuyez sur « Vérifier ».

Essayez vous-même

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"));
    }
}

Toutes les leçons de Créer de vrais jeux

Entraînez-vous par vous-même : Playground Unity