Conserver entre les scènes
Fait partie de la section Créer de vrais jeux du Journey Unity de Coddy. Leçon 20 sur 56.
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, dans une scène qui lui est propre, appelée DontDestroyOnLoad dans la fenêtre Hierarchy pendant le mode Play, que les chargements ne touchent jamais. Cela ne fonctionne que sur un objet racine : sur un enfant, Unity affiche un avertissement et ne conserve rien. Les enfants de l’objet conservé l’accompagnent, 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 considéré comme égal à null.
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 déroulement est Menu, Level1, puis retour à 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 remplacerait 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 lui, 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.
Défi
FacileUn chronomètre de speedrun. L’objet RunClock dans Level1 compte les secondes de toute la partie et enregistre un temps intermédiaire chaque fois qu’un niveau est terminé. Le Goal doré de Level1 charge Level2, dont le goal charge à nouveau Level1, et chaque goal appelle d’abord RunClock.Instance.Split(). Chaque niveau a son propre HUD avec un ClockText ; dans l’Inspector, on attribue au RunClock celui de Level1. Les flèches déplacent le Player. Modifie RunClock.cs afin que :
- le chronomètre continue de tourner lors du chargement de chaque scène, sans repartir de zéro ;
- le temps s’affiche toujours dans le
ClockTextdu niveau ouvert, sous la formeTime: 12.3; - en revenant à Level1, qui possède son propre RunClock, il n’y ait toujours qu’un seul chronomètre, celui qui tourne déjà, et que
RunClock.Instancesoit celui-ci.
Appuie sur Play, va dans Level2 puis reviens, et termine à nouveau Level1, puis clique sur Check.
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"));
}
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Créer de vrais jeux
1Texte à l’écran
Canvas et texteAfficher le scoreFormater les nombresUn compte à reboursRécapitulatif : compteur de vitesse4Scènes et niveaux
Charger une scèneRedémarrer le niveauNiveau suivantConserver entre les scènesRécapitulatif : sélection du niveau7Contrôle du temps
Mettre en pause avec timeScaleRalentiTemps non mis à l’échelleRécapitulatif : Bullet Time10Projet : jeu de plateforme en 3D
Le parcoursPlateformes mobiles2Boutons et écrans
Boutons et onClickLambdasRelier les éléments dans l’InspectorActiver et désactiver les panneauxBarres de santéRécapitulatif : boutique d’améliorations5Sauvegarder avec PlayerPrefs
Enregistrer un nombreCharger avec une valeur par défautMeilleur scoreEnregistrer les paramètresRécapitulatif : les pièces à la banque