Eine ideale Methode zum Speichern von Variablen zwischen Szenen ist die Verwendung einer Singleton-Manager-Klasse. Indem Sie eine Klasse zum Speichern persistenter Daten erstellen und diese Klasse auf DoNotDestroyOnLoad()
festlegen, können Sie sicherstellen, dass sofort auf sie zugegriffen werden kann und sie zwischen Szenen bestehen bleibt.
Eine weitere Option ist die Verwendung der PlayerPrefs
Klasse. PlayerPrefs
dient zum Speichern von Daten zwischen Wiedergabesitzungen , dient jedoch weiterhin zum Speichern von Daten zwischen Szenen .
Verwenden einer Singleton-Klasse und DoNotDestroyOnLoad()
Das folgende Skript erstellt eine persistente Singleton-Klasse. Eine Singleton-Klasse ist eine Klasse, die so konzipiert ist, dass sie nur eine Instanz gleichzeitig ausführt. Durch die Bereitstellung dieser Funktionalität können wir sicher eine statische Selbstreferenz erstellen, um von überall auf die Klasse zuzugreifen. Dies bedeutet, dass Sie direkt auf die Klasse zugreifen können DataManager.instance
, einschließlich aller öffentlichen Variablen innerhalb der Klasse.
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);
}
}
Unten sehen Sie den Singleton in Aktion. Beachten Sie, dass das DataManager-Objekt in der Hierarchieansicht von der szenenspezifischen Überschrift in die Überschrift "DontDestroyOnLoad" verschoben wird, sobald ich die erste Szene ausführe.
Mit der PlayerPrefs
Klasse
Unity verfügt über eine integrierte Klasse zur Verwaltung grundlegender persistenter DatenPlayerPrefs
. Alle Daten, die an die PlayerPrefs
Datei übergeben werden, bleiben während der gesamten Spielsitzung erhalten , sodass sie natürlich auch szenenübergreifend gespeichert werden können.
Die PlayerPrefs
Datei kann Variablen der Typen speichern string
, int
und float
. Wenn wir Werte in die PlayerPrefs
Datei einfügen , geben wir einen zusätzlichen string
als Schlüssel an. Wir verwenden denselben Schlüssel, um unsere Werte später aus der PlayerPref
Datei abzurufen .
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();
}
}
Beachten Sie, dass ich beim Umgang mit der PlayerPrefs
Datei zusätzliche Vorsichtsmaßnahmen einhalte:
- Ich habe jeden Schlüssel als gespeichert
private static string
. Auf diese Weise kann ich garantieren, dass ich immer den richtigen Schlüssel verwende. Wenn ich den Schlüssel aus irgendeinem Grund ändern muss, muss ich nicht sicherstellen, dass ich alle Verweise darauf ändere.
- Ich speichere die
PlayerPrefs
Datei nach dem Schreiben auf die Festplatte. Dies wird wahrscheinlich keinen Unterschied machen, wenn Sie die Datenpersistenz nicht über mehrere Wiedergabesitzungen hinweg implementieren. PlayerPrefs
wird während des Schließens einer normalen Anwendung auf der Festplatte gespeichert, wird jedoch möglicherweise nicht automatisch aufgerufen, wenn Ihr Spiel abstürzt.
- Ich tatsächlich überprüfen , dass jeder Schlüssel existiert in der
PlayerPrefs
, bevor ich mit ihr verbundenen Wert abzurufen versuchen. Dies mag sinnlos erscheinen, aber es ist eine gute Übung, dies zu überprüfen.
- Ich habe eine
Delete
Methode, die die PlayerPrefs
Datei sofort löscht . Wenn Sie nicht beabsichtigen, die Datenpersistenz über Wiedergabesitzungen hinweg zu berücksichtigen, können Sie diese Methode auch aufrufen Awake
. Durch Löschen der PlayerPrefs
Datei zu Beginn jedes Spiels, stellen Sie sicher , dass alle Daten , die haben aus der vorherigen Sitzung bestehen nicht fälschlicherweise als Daten aus der behandelt aktuellen Sitzung.
PlayerPrefs
Unten sehen Sie in Aktion. Wenn ich auf "Daten speichern" klicke, rufe ich die Save
Methode direkt auf und wenn ich auf "Daten laden" klicke, rufe ich die Load
Methode direkt auf . Ihre eigene Implementierung wird wahrscheinlich variieren, zeigt aber die Grundlagen.
Abschließend möchte ich darauf hinweisen, dass Sie das Grundlegende erweitern PlayerPrefs
können, um nützlichere Typen zu speichern. JPTheK9 bietet eine gute Antwort auf eine ähnliche Frage , in der ein Skript zum Serialisieren von Arrays in Zeichenfolgenform zum Speichern in einer PlayerPrefs
Datei bereitgestellt wird . Sie verweisen auch auf das Unify Community-Wiki , in dem ein Benutzer ein umfangreicheres PlayerPrefsX
Skript hochgeladen hat , um die Unterstützung einer größeren Vielfalt von Typen wie Vektoren und Arrays zu ermöglichen.