In dieser Antwort sind die grundlegenden Möglichkeiten aufgeführt, mit dieser Situation umzugehen. Die meisten dieser Methoden lassen sich jedoch nicht gut auf große Projekte skalieren. Wenn Sie etwas Skalierbareres möchten und keine Angst haben, sich die Hände schmutzig zu machen, lesen Sie die Antwort von Lea Hayes zu den Frameworks von Dependency Injection .
1. Ein statisches Skript, das nur Daten enthält
Sie können ein statisches Skript erstellen, das nur Daten enthält. Da es statisch ist, müssen Sie es keinem GameObject zuweisen. Sie können einfach auf Ihre Daten zugreifen, wie z ScriptName.Variable = data;
.
Vorteile:
- Keine Instanz oder Singleton erforderlich.
- Sie können von überall in Ihrem Projekt auf Daten zugreifen.
- Kein zusätzlicher Code zum Übergeben von Werten zwischen Szenen.
- Alle Variablen und Daten in einem einzigen datenbankähnlichen Skript erleichtern die Handhabung.
Nachteile:
- Sie können keine Coroutine innerhalb des statischen Skripts verwenden.
- Sie werden wahrscheinlich riesige Zeilen mit Variablen in einer einzelnen Klasse haben, wenn Sie nicht gut organisiert sind.
- Sie können im Editor keine Felder / Variablen zuweisen.
Ein Beispiel:
public static class PlayerStats
{
private static int kills, deaths, assists, points;
public static int Kills
{
get
{
return kills;
}
set
{
kills = value;
}
}
public static int Deaths
{
get
{
return deaths;
}
set
{
deaths = value;
}
}
public static int Assists
{
get
{
return assists;
}
set
{
assists = value;
}
}
public static int Points
{
get
{
return points;
}
set
{
points = value;
}
}
}
2. DontDestroyOnLoad
Wenn Sie Ihr Skript muss ein Gameobject zugeordnet werden oder leiten sich von MonoBehavior, dann können Sie hinzufügen DontDestroyOnLoad(gameObject);
Zeile in die Klasse , wo es einmal ausgeführt werden kann (Platzierung es in Awake()
ist usally der Weg für diese zu gehen) .
Vorteile:
- Alle MonoBehaviour-Jobs (zum Beispiel Coroutines) können sicher ausgeführt werden.
- Sie können Felder im Editor zuweisen.
Nachteile:
- Wahrscheinlich müssen Sie Ihre Szene je nach Skript anpassen.
- Möglicherweise müssen Sie überprüfen, welches secene geladen ist, um festzustellen, was in Update oder anderen allgemeinen Funktionen / Methoden zu tun ist. Wenn Sie beispielsweise in Update () etwas mit der Benutzeroberfläche tun, müssen Sie überprüfen, ob die richtige Szene geladen ist, um den Job auszuführen. Dies führt zu einer Vielzahl von If-else- oder Switch-Case-Überprüfungen.
3. PlayerPrefs
Sie können dies implementieren, wenn Sie möchten, dass Ihre Daten auch dann gespeichert werden, wenn das Spiel geschlossen wird.
Vorteile:
- Einfach zu verwalten, da Unity den gesamten Hintergrundprozess abwickelt.
- Sie können Daten nicht nur zwischen Szenen, sondern auch zwischen Instanzen (Spielsitzungen) übertragen.
Nachteile:
- Verwendet das Dateisystem.
- Daten können einfach aus der Prefs-Datei geändert werden.
4. Speichern in eine Datei
Dies ist ein wenig zu viel für das Speichern von Werten zwischen Szenen. Wenn Sie keine Verschlüsselung benötigen, rate ich Ihnen von dieser Methode ab.
Vorteile:
- Sie haben die Kontrolle über die im Gegensatz zu PlayerPrefs gespeicherten Daten.
- Sie können Daten nicht nur zwischen Szenen, sondern auch zwischen Instanzen (Spielsitzungen) übertragen.
- Sie können die Datei übertragen (benutzergeneriertes Inhaltskonzept stützt sich darauf).
Nachteile:
- Schleppend.
- Verwendet das Dateisystem.
- Möglichkeit von Lese- / Ladekonflikten durch Stream-Unterbrechung beim Speichern.
- Daten können einfach aus der Datei geändert werden, es sei denn, Sie implementieren eine Verschlüsselung (wodurch der Code noch langsamer wird).
5. Singleton-Muster
Singleton-Pattern ist ein sehr aktuelles Thema in der objektorientierten Programmierung. Einige schlagen es vor, andere nicht. Informieren Sie sich selbst und rufen Sie entsprechend den Bedingungen Ihres Projekts an.
Vorteile:
- Einfach einzurichten und zu verwenden.
- Sie können von überall in Ihrem Projekt auf Daten zugreifen.
- Alle Variablen und Daten in einem einzigen datenbankähnlichen Skript erleichtern die Handhabung.
Nachteile:
- Viele Boilerplate-Codes, deren einzige Aufgabe es ist, die Singleton-Instanz zu warten und zu sichern.
- Es gibt starke Argumente gegen die Verwendung von Singleton-Mustern . Seien Sie vorsichtig und recherchieren Sie vorher.
- Möglichkeit eines Datenkonflikts aufgrund einer schlechten Implementierung.
- Unity hat möglicherweise Schwierigkeiten, mit Singleton-Mustern umzugehen 1 .
1 : In der Zusammenfassung der OnDestroy
Methode von Singleton Script, die im Unify Wiki bereitgestellt wird , können Sie sehen, wie der Autor Geisterobjekte beschreibt , die zur Laufzeit in den Editor eingeblutet wurden:
Wenn Unity beendet wird, werden Objekte in zufälliger Reihenfolge zerstört. Grundsätzlich wird ein Singleton nur dann zerstört, wenn die Anwendung beendet wird. Wenn ein Skript Instance aufruft, nachdem es zerstört wurde, wird ein fehlerhaftes Geisterobjekt erstellt, das auch nach dem Beenden der Wiedergabe der Anwendung in der Editor-Szene verbleibt. Wirklich schlecht! Das wurde gemacht, um sicherzugehen, dass wir dieses fehlerhafte Geisterobjekt nicht erstellen.
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.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
KlasseUnity verfügt über eine integrierte Klasse zur Verwaltung grundlegender persistenter Daten
PlayerPrefs
. Alle Daten, die an diePlayerPrefs
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 speichernstring
,int
undfloat
. Wenn wir Werte in diePlayerPrefs
Datei einfügen , geben wir einen zusätzlichenstring
als Schlüssel an. Wir verwenden denselben Schlüssel, um unsere Werte später aus derPlayerPref
Datei abzurufen .Beachten Sie, dass ich beim Umgang mit der
PlayerPrefs
Datei zusätzliche Vorsichtsmaßnahmen einhalte: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.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.PlayerPrefs
, bevor ich mit ihr verbundenen Wert abzurufen versuchen. Dies mag sinnlos erscheinen, aber es ist eine gute Übung, dies zu überprüfen.Delete
Methode, die diePlayerPrefs
Datei sofort löscht . Wenn Sie nicht beabsichtigen, die Datenpersistenz über Wiedergabesitzungen hinweg zu berücksichtigen, können Sie diese Methode auch aufrufenAwake
. Durch Löschen derPlayerPrefs
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 dieSave
Methode direkt auf und wenn ich auf "Daten laden" klicke, rufe ich dieLoad
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 einerPlayerPrefs
Datei bereitgestellt wird . Sie verweisen auch auf das Unify Community-Wiki , in dem ein Benutzer ein umfangreicheresPlayerPrefsX
Skript hochgeladen hat , um die Unterstützung einer größeren Vielfalt von Typen wie Vektoren und Arrays zu ermöglichen.quelle