Un moyen idéal de stocker des variables entre les scènes consiste à utiliser une classe de gestionnaire singleton. En créant une classe pour stocker des données persistantes et en lui affectant une valeur DoNotDestroyOnLoad()
, vous pouvez vous assurer qu'elle est immédiatement accessible et persiste entre les scènes.
Une autre option consiste à utiliser la PlayerPrefs
classe. PlayerPrefs
est conçu pour vous permettre de sauvegarder des données entre les sessions de lecture , mais il servira toujours de moyen de sauvegarder des données entre des scènes .
Utiliser une classe singleton et DoNotDestroyOnLoad()
Le script suivant crée une classe singleton persistante. Une classe singleton est une classe conçue pour n'exécuter qu'une seule instance à la fois. En fournissant une telle fonctionnalité, nous pouvons créer en toute sécurité une référence de soi statique, pour accéder à la classe de n'importe où. Cela signifie que vous pouvez accéder directement à la classe avec DataManager.instance
, y compris toutes les variables publiques de la classe.
using UnityEngine;
/// <summary>Manages data for persistance between levels.</summary>
public class DataManager : MonoBehaviour
{
/// <summary>Static reference to the instance of our DataManager</summary>
public static DataManager instance;
/// <summary>The player's current score.</summary>
public int score;
/// <summary>The player's remaining health.</summary>
public int health;
/// <summary>The player's remaining lives.</summary>
public int lives;
/// <summary>Awake is called when the script instance is being loaded.</summary>
void Awake()
{
// If the instance reference has not been set, yet,
if (instance == null)
{
// Set this instance as the instance reference.
instance = this;
}
else if(instance != this)
{
// If the instance reference has already been set, and this is not the
// the instance reference, destroy this game object.
Destroy(gameObject);
}
// Do not destroy this object, when we load a new scene.
DontDestroyOnLoad(gameObject);
}
}
Vous pouvez voir le singleton en action, ci-dessous. Notez que dès que j'exécute la scène initiale, l'objet DataManager passe de l'en-tête spécifique à la scène à l'en-tête "DontDestroyOnLoad", dans la vue hiérarchique.
Utiliser la PlayerPrefs
classe
Unity a une classe intégrée pour gérer les données persistantes de base appeléesPlayerPrefs
. Toutes les données validées dans le PlayerPrefs
fichier persisteront au cours des sessions de jeu . Il est donc naturellement capable de conserver des données dans des scènes.
Le PlayerPrefs
fichier peut stocker des variables de types string
, int
et float
. Lorsque nous insérons des valeurs dans le PlayerPrefs
fichier, nous fournissons une string
clé supplémentaire . Nous utilisons la même clé pour extraire ultérieurement nos valeurs du PlayerPref
fichier.
using UnityEngine;
/// <summary>Manages data for persistance between play sessions.</summary>
public class SaveManager : MonoBehaviour
{
/// <summary>The player's name.</summary>
public string playerName = "";
/// <summary>The player's score.</summary>
public int playerScore = 0;
/// <summary>The player's health value.</summary>
public float playerHealth = 0f;
/// <summary>Static record of the key for saving and loading playerName.</summary>
private static string playerNameKey = "PLAYER_NAME";
/// <summary>Static record of the key for saving and loading playerScore.</summary>
private static string playerScoreKey = "PLAYER_SCORE";
/// <summary>Static record of the key for saving and loading playerHealth.</summary>
private static string playerHealthKey = "PLAYER_HEALTH";
/// <summary>Saves playerName, playerScore and
/// playerHealth to the PlayerPrefs file.</summary>
public void Save()
{
// Set the values to the PlayerPrefs file using their corresponding keys.
PlayerPrefs.SetString(playerNameKey, playerName);
PlayerPrefs.SetInt(playerScoreKey, playerScore);
PlayerPrefs.SetFloat(playerHealthKey, playerHealth);
// Manually save the PlayerPrefs file to disk, in case we experience a crash
PlayerPrefs.Save();
}
/// <summary>Saves playerName, playerScore and playerHealth
// from the PlayerPrefs file.</summary>
public void Load()
{
// If the PlayerPrefs file currently has a value registered to the playerNameKey,
if (PlayerPrefs.HasKey(playerNameKey))
{
// load playerName from the PlayerPrefs file.
playerName = PlayerPrefs.GetString(playerNameKey);
}
// If the PlayerPrefs file currently has a value registered to the playerScoreKey,
if (PlayerPrefs.HasKey(playerScoreKey))
{
// load playerScore from the PlayerPrefs file.
playerScore = PlayerPrefs.GetInt(playerScoreKey);
}
// If the PlayerPrefs file currently has a value registered to the playerHealthKey,
if (PlayerPrefs.HasKey(playerHealthKey))
{
// load playerHealth from the PlayerPrefs file.
playerHealth = PlayerPrefs.GetFloat(playerHealthKey);
}
}
/// <summary>Deletes all values from the PlayerPrefs file.</summary>
public void Delete()
{
// Delete all values from the PlayerPrefs file.
PlayerPrefs.DeleteAll();
}
}
Notez que je prends des précautions supplémentaires lors de la manipulation du PlayerPrefs
fichier:
- J'ai enregistré chaque clé en tant que
private static string
. Cela me permet de garantir que j'utilise toujours la bonne clé. Cela signifie que si je dois changer la clé pour une raison quelconque, je n'ai pas besoin de changer toutes les références à la clé.
- Je sauvegarde le
PlayerPrefs
fichier sur le disque après y avoir écrit. Cela ne fera probablement pas de différence si vous n'implémentez pas la persistance des données dans les sessions de lecture. PlayerPrefs
sera sauvegardé sur le disque lors d’une fermeture d’application normale, mais il se peut qu’il n’appelle pas naturellement si votre jeu plante.
- Je vérifie réellement que chaque clé existe dans le
PlayerPrefs
, avant d'essayer de récupérer une valeur qui lui est associée. Cela peut sembler une double vérification inutile, mais c'est une bonne pratique.
- J'ai une
Delete
méthode qui efface immédiatement le PlayerPrefs
fichier. Si vous n'avez pas l'intention d'inclure la persistance des données entre les sessions de lecture, vous pouvez envisager d'appeler cette méthode sur Awake
. En effaçant le PlayerPrefs
fichier au début de chaque jeu, assurez - vous que toutes les données qui ne persistent de la session précédente ne sont pas traitées à tort que les données de la actuelle session.
Vous pouvez voir PlayerPrefs
en action, ci-dessous. Notez que lorsque je clique sur "Enregistrer les données", j'appelle directement la Save
méthode et lorsque je clique sur "Charger les données", j'appelle directement la Load
méthode. Votre propre implémentation variera probablement, mais elle démontrera les bases.
Pour terminer, je dois souligner que vous pouvez développer la base PlayerPrefs
pour stocker des types plus utiles. JPTheK9 fournit une bonne réponse à une question similaire , dans laquelle ils fournissent un script pour la sérialisation de tableaux sous forme de chaîne, à stocker dans un PlayerPrefs
fichier. Ils nous indiquent également le wiki de la communauté Unify , où un utilisateur a téléchargé un PlayerPrefsX
script plus volumineux pour permettre la prise en charge d'une plus grande variété de types, tels que les vecteurs et les tableaux.