Laden und Standardwerte
Teil des Abschnitts Spielarchitektur in Unity der Unity-Journey von Coddy. Lektion 26 von 50.
Beim Laden muss der Umgang mit nicht vorhandenen oder unvollständigen Speicherständen berücksichtigt werden. Ein Rennspiel speichert ein RaceSave; Version 2 des Spiels hat musicVolume hinzugefügt:
[System.Serializable]
public class RaceSave
{
public int trophies;
public string car = "Rookie Kart";
public float musicVolume = 0.8f;
}RaceSave save;
if (File.Exists(path))
{
save = JsonUtility.FromJson<RaceSave>(File.ReadAllText(path));
}
else
{
save = new RaceSave();
}Ein neuer Spieler hat keine Datei, und File.ReadAllText löst bei einer fehlenden Datei eine FileNotFoundException aus. Prüfe deshalb zuerst File.Exists und beginne mit new RaceSave(): 0 Trophäen, das Rookie Kart und Lautstärke 0.8 – die Feldinitialisierer. In der Datei eines alten Spielers mit Version 1 steht {"trophies":3,"car":"Red Racer"}. FromJson erstellt ein neues RaceSave, wobei die Feldinitialisierer ausgeführt werden, und setzt dann nur die Schlüssel, die im JSON vorhanden sind, sodass musicVolume den Wert 0.8 hat. Ein Schlüssel, für den es in der Klasse kein Feld gibt, wird ignoriert. Eine neue Spielversion kann daher alte Speicherstände lesen, solange jedes neue Feld einen Initialisierer mit einem sinnvollen Wert hat.
JsonUtility.FromJsonOverwrite(json, obj) füllt ein bereits vorhandenes Objekt, anstatt eines zu erstellen, und lässt alle Felder, die im JSON fehlen, unverändert. FromJson kann kein MonoBehaviour oder ScriptableObject erstellen (Unity löst Cannot deserialize JSON to new instances of type 'RaceSettings.' aus), daher wird ein Einstellungs-Asset durch Überschreiben geladen: JsonUtility.FromJsonOverwrite(json, settings);. Beim Überschreiben bleiben außerdem die Werte erhalten, die ein Objekt bereits enthält, etwa die Werte, die ihm der Inspector zugewiesen hat; FromJson würde stattdessen die Initialisierer der Klasse wiederherstellen.
Aufgabe
MittelDas virtuelle Haustier lädt pet.json, wenn das Spiel startet, und mit der Leertaste wird das Haustier gefüttert und gespeichert. Beim Laden gibt es zwei Probleme:
- Ein neuer Spieler hat keine
pet.json, und Start bricht mit einer FileNotFoundException ab. Wenn keine Datei vorhanden ist, behalte das Haustier bei, das im Inspector eingerichtet wurde (Biscuit, Hunger 30, Glück 80, ein Ball), und protokolliereA new pet: Biscuit. - In Version 1 des Spiels wurden nur
petNameundhungergespeichert;happinessundtoyskamen in Version 2 hinzu (siehe PetSave.cs). Beim Laden eines alten Speicherstands mit FromJson erhält man die 50 der Klasse und keine Spielzeuge, nicht die Werte aus dem Inspector. Lade eine vorhandene Datei mitJsonUtility.FromJsonOverwriteinpet, damit Werte, die in der Datei fehlen, den Wert aus dem Inspector beibehalten, und protokolliere die Begrüßung mit dem geladenen Namen, alsoWelcome back, Mochi.
Drücke Play und füttere das Haustier, dann Stop und erneut Play, danach Check.
Probier es selbst
using System.IO;
using UnityEngine;
using UnityEngine.InputSystem;
using TMPro;
public class PetCare : MonoBehaviour
{
public PetSave pet;
public TMP_Text petText;
private string path;
void Start()
{
path = Path.Combine(Application.persistentDataPath, "pet.json");
pet = JsonUtility.FromJson<PetSave>(File.ReadAllText(path));
Show();
}
void Update()
{
if (Keyboard.current.spaceKey.wasPressedThisFrame)
{
pet.hunger = Mathf.Max(pet.hunger - 10, 0);
pet.happiness = Mathf.Min(pet.happiness + 5, 100);
File.WriteAllText(path, JsonUtility.ToJson(pet));
Show();
}
}
void Show()
{
petText.text = pet.petName + ": hunger " + pet.hunger + ", happiness " + pet.happiness;
}
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Spielarchitektur in Unity
1Komponenten statt Hierarchien
Kleine KomponentenEin Basisskript für GegnerAbstrakte KomponentenKomponenten im ZusammenspielRückblick: Modularer Geschützturm4Serialisierte Daten
Serialisierbare KlassenListen im InspectorEnums im InspectorRückblick: Loot-Tabelle7Zustandsautomaten
Zustände als KlassenEin ZustandsautomatÜbergängeGegner-KIWiederholung: Türzustände10Projekt: Arena-Überlebenskampf
Der HeldGegnertypen2Interfaces in Unity
IDamageableInterfaces und TryGetComponentGetComponentsRückblick: Interaktionstaste5ScriptableObjects
Daten-AssetsWaffenwerteGemeinsame EinstellungenWellen als DatenRückblick: Item-Datenbank8Wiederverwendbarer Code
ErweiterungsmethodenEin generisches SingletonGenerische HilfsmethodenRückblick: FindNearest