Games

Dauerhafte Daten: Wie Sie Ihre Spielstände und Einstellungen speichern

BRONSON ZGEB / UNITY TECHNOLOGIESSenior Content Developer
Feb 23, 2021|10 Min.
Dauerhafte Daten: Wie Sie Ihre Spielstände und Einstellungen speichern
Diese Website wurde aus praktischen Gründen für Sie maschinell übersetzt. Die Richtigkeit und Zuverlässigkeit des übersetzten Inhalts kann von uns nicht gewährleistet werden. Sollten Sie Zweifel an der Richtigkeit des übersetzten Inhalts haben, schauen Sie sich bitte die offizielle englische Version der Website an.

Das Speichern von Daten ist für jedes Spiel entscheidend. Ganz gleich, ob Sie Highscores, Einstellungen oder einen Spielstatus speichern müssen, Unity bietet eine Vielzahl von Methoden - von PlayerPrefs bis hin zur Serialisierung von Daten, ihrer Verschlüsselung und dem Schreiben in eine Datei.

Aktualisiert am 23. Juni 2021: Im Rahmen von Unite Now 2020 habe ich eine Session mit Tipps zur Datenpersistenz in Unity erstellt. Er deckt einige der üblichen Möglichkeiten zum Speichern und Laden von Daten in Ihrem Unity-Projekt ab, ist aber keineswegs eine erschöpfende Liste. Das heißt, es gibt mehr Möglichkeiten, Daten zu serialisieren, als Sie jemals brauchen werden, und jeder Ansatz löst ein bestimmtes Problem und hat seine eigenen Stärken und Schwächen. Dieser Blog-Beitrag behandelt die gleichen Methoden, die ich in der Unite Now-Sitzung besprochen habe.

PlayerPrefs

PlayerPrefs sind nicht zum Speichern von Spielständen gedacht. Aber sie sind nützlich, also werden wir sie besprechen. Sie können PlayerPrefs verwenden, um die Voreinstellungen eines Players zwischen den Sitzungen zu speichern, z. B. Qualitätseinstellungen, Audiolautstärke oder andere unwichtige Daten. PlayerPrefs werden irgendwo auf Ihrem Gerät gespeichert, getrennt von Ihrem Projekt. Der genaue Speicherort hängt von Ihrem Betriebssystem ab, aber in der Regel befindet er sich an einem Ort, der global zugänglich ist und von Ihrem Betriebssystem verwaltet wird. Die gespeicherten Daten bestehen aus einfachen Schlüssel-Wert-Paaren. Da sie leicht zugänglich sind, sind sie nicht sicher vor Benutzern, die sie öffnen und ändern möchten, und sie können versehentlich gelöscht werden, da sie außerhalb des Projekts gespeichert und von Ihrem Betriebssystem verwaltet werden.

PlayerPrefs sind relativ einfach zu implementieren und erfordern nur ein paar Zeilen Code. Allerdings unterstützen sie nur Werte vom Typ Float, Int und String, was die Serialisierung großer, komplexer Objekte erschwert. Ein entschlossener Benutzer kann diese Einschränkung überwinden, indem er seine gespeicherten Daten in ein Format konvertiert, das durch einen dieser Grundtypen repräsentiert wird. Ich empfehle dies jedoch nicht, da es bessere Tools zum Speichern Ihrer Daten gibt.

public void SavePrefs()
{
    PlayerPrefs.SetInt("Volume", 50);
    PlayerPrefs.Save();
}
 
public void LoadPrefs()
{
    int volume = PlayerPrefs.GetInt("Volume", 0); 
}

Da jede Unity-Anwendung alle PlayerPrefs in einer einzigen Datei speichert, eignet sie sich nicht für den Umgang mit mehreren Speicherdateien oder Cloud Saves, bei denen Sie die Speicherdaten an einem anderen Ort speichern und empfangen müssen.

JSON

JSON ist ein von Menschen lesbares Datenformat. Das heißt, sie wird von Menschen und Maschinen gleichermaßen leicht verstanden - was sowohl Vor- als auch Nachteile hat. Es ist viel einfacher, Ihre gespeicherten Daten zu debuggen oder neue Speicherdaten zu Testzwecken zu erstellen, wenn Sie sie lesen und verstehen können, aber andererseits ist es auch für Spieler einfach, die Daten zu lesen und zu verändern. Die Möglichkeit, Daten zu lesen und zu ändern, ist nützlich, wenn Sie Modding unterstützen, aber schädlich, wenn Sie Cheating verhindern wollen. Hinzu kommt, dass JSON ein textbasiertes Format ist, das für Maschinen aufwendiger zu parsen ist. Das heißt, sie sind langsamer beim Lesen und benötigen mehr Speicher als binäre Alternativen. Wenn Sie also viele Daten haben, sollten Sie Optionen in Betracht ziehen, die nicht textbasiert sind. Jeder Anwendungsfall ist anders, und genau diese Art von Kompromissen veranlasst die Entwickler, viele andere Datenformate zu entwickeln.

JSON ist standardisiert und wird in vielen verschiedenen Anwendungen verwendet. Daher wird es von allen Plattformen stark unterstützt, was bei der Entwicklung plattformübergreifender Spiele hilfreich ist. JSON wurde als Kommunikationsprotokoll für Webbrowser entwickelt und eignet sich daher von Natur aus für die Übertragung von Daten über ein Netzwerk. Aus diesem Grund eignet sich JSON hervorragend zum Senden und Empfangen von Daten von einem Server-Backend.

JsonUtility

JsonUtility ist die in Unity integrierte API zum Serialisieren und Deserialisieren von JSON-Daten. Ähnlich wie PlayerPrefs ist auch diese Funktion relativ einfach zu implementieren. Im Gegensatz zu PlayerPrefs müssen Sie die JSON-Daten jedoch selbst speichern, entweder in einer Datei oder über ein Netzwerk. Wenn Sie die Datenspeicherung selbst in die Hand nehmen, können Sie problemlos mehrere Speicherdateien verwalten, da Sie jede Datei an einem anderen Ort speichern können. Um dies zu erleichtern, habe ich einen einfachen Dateimanager geschrieben, der in diesem Beispiel-Repository verfügbar ist.

Es ist wichtig zu erwähnen, dass JsonUtility keine voll funktionsfähige JSON-Implementierung ist. Wenn Sie es gewohnt sind, mit JSON-Daten zu arbeiten, wird Ihnen vielleicht die fehlende Unterstützung für bestimmte Funktionen auffallen. Wenn Sie daran interessiert sind, die Leistung verschiedener JSON-Lösungen zu vergleichen, sollten Sie dieses Benchmarking-Projekt ausprobieren. Denken Sie daran, dass es am besten ist, wenn Sie den Test auf Ihrem Zielgerät durchführen.

Für JsonUtility gelten die gleichen Einschränkungen wie für den internen Unity-Serializer. Das heißt, wenn Sie ein Feld nicht im Inspector serialisieren können, können Sie es auch nicht in JSON serialisieren. Um diese Einschränkungen zu umgehen, können Sie Plain Old Data-Typen (oder PODS) erstellen, die alle Ihre Speicherdaten enthalten. Wenn es an der Zeit ist, zu speichern, übertragen Sie Ihre Daten aus den Laufzeittypen in einen POD und speichern diesen auf einer Festplatte. Bei Bedarf können Sie auch benutzerdefinierte Serialisierungs-Callbacks erstellen, um Typen zu unterstützen, die der Serializer von Unity standardmäßig nicht unterstützt.

Zum Thema JsonUtility ist EditorJsonUtility ein weiteres nützliches Tool. Während JsonUtility für jedes MonoBehaviour oder ScriptableObject-basierte Objekt funktioniert, funktioniert EditorJsonUtility für jeden Unity-Engine-Typ. Sie können also eine JSON-Darstellung eines beliebigen Objekts im Unity-Editor erstellen - oder in die andere Richtung gehen und ein Asset aus einer JSON-Datei erstellen.

Andere Bibliotheken

Neben den eingebauten Serialisierungsoptionen gibt es weitere externe Bibliotheken, die Sie ebenfalls verwenden können. Sofern Sie nicht ausdrücklich ein textbasiertes Format für die Lesbarkeit verwenden müssen, ist es am besten, einen binärbasierten Serialisierer zu verwenden:

Binäre Werkzeuge

  • MessagePack ist ein effizienter binärer Serialisierer. Es ist leistungsfähig und relativ einfach zu bedienen. Wie JSON ist es auf fast allen Plattformen verfügbar, so dass Sie es verwenden können, um Daten über Netzwerke zu senden und mit Backend-Servern zu kommunizieren. Sie können hier mehr darüber lesen.
  • ProtoBuf und Protobuf-net ist ein weiterer ähnlicher binärer Serialisierer. Außerdem ist es schnell und effizient. Google hat es als leistungsstarke Alternative zu bestehenden Formaten wie XML entwickelt. Wie JSON und MessagePack ist es auch gut für die Kommunikation über Netzwerke geeignet.
  • BinaryFormatter ist eine DotNet-Bibliothek, mit der Sie Ihre Objekte direkt in einem Binärformat speichern können. BinaryFormatter hat jedoch gefährliche Sicherheitslücken und sollte vermieden werden. Ich wiederhole: Verwenden Sie BinaryFormatter nicht. Weitere Informationen über die Sicherheitsrisiken finden Sie hier.

Text-Tools

  • EasySave ist ein gut unterstütztes und beliebtes Plug-in, das im Unity Asset Store erhältlich ist. Damit können Sie alle Ihre Daten speichern, ohne Code zu schreiben, was für Anfänger hervorragend geeignet ist. Außerdem verfügt es über eine leistungsstarke und flexible API, die es auch für fortgeschrittene Benutzer ideal macht. Es ist zwar nicht kostenlos, aber den Preis wert, wenn Sie eine voll funktionsfähige, sofort einsatzbereite Lösung suchen.
  • JSON.Net ist eine kostenlose und quelloffene JSON-Implementierung für alle DotNet-Plattformen. Im Gegensatz zum eingebauten JsonUtility ist es voll funktionsfähig. Dies hat jedoch seinen Preis, denn es ist deutlich weniger leistungsfähig als das integrierte JsonUtility. Die Standardversion unterstützt nicht alle Unity-Plattformen, aber es gibt eine modifizierte Version im Unity Asset Store, die zusätzliche Unterstützung bietet.
  • XML ist ein alternatives Datenformat. Wie JSON ist es relativ gut lesbar und verfügt über einige Funktionen, die für Ihre spezielle Anwendung nützlich sein könnten, wie z. B. Namespaces. DotNet verfügt über integrierte Unterstützung für XML.
Datensicherheit

Wenn es um Sicherheit geht, denken die meisten Menschen zuerst an Verschlüsselung. Wenn es jedoch darum geht, Daten lokal auf dem Gerät eines Spielers zu speichern, ist die Verschlüsselung relativ leicht zu überwinden. Auch ohne die Verschlüsselung zu knacken, können Benutzer die Daten mit frei verfügbaren Tools direkt im Speicher manipulieren. Mit anderen Worten: Sie können davon ausgehen, dass alles, was lokal gespeichert wird, nicht vertrauenswürdig ist.

Wenn Sie echte Sicherheit benötigen, ist es am besten, wenn Sie Ihre Daten auf einem Server aufbewahren, wo Benutzer sie nicht verändern können. Damit dies funktioniert, sollte die Anwendung keine Daten direkt an den Server senden, da die Benutzer diese noch manipulieren könnten. Stattdessen kann die Anwendung nur Befehle an den Server senden, den Server die Daten ändern lassen und dann die Ergebnisse an die Anwendung zurücksenden. Wenn also Datensicherheit für Sie lebenswichtig ist, ist es am besten, so früh wie möglich Bescheid zu wissen, denn das wird sich auf die Architektur Ihres Projekts auswirken.

Weitere Informationen zur Serialisierung finden Sie auf der Handbuchseite. Wenn Sie dies in Aktion sehen möchten, sehen Sie sich die begleitende Unite Now-Sitzung an.