Laden und Standardwerte
Teil des Abschnitts Spielarchitektur in Unity der Unity-Journey von Coddy. Lektion 32 von 64.
Beim Laden muss berücksichtigt werden, dass Speicherstände fehlen oder unvollständig sein können. Ein Rennspiel speichert einen RaceSave; in Version 2 des Spiels wurde 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 daher zuerst File.Exists und beginne mit new RaceSave(): 0 Trophäen, der Rookie Kart und Lautstärke 0.8 – die Feldinitialisierungen. In der Datei eines Spielers mit der alten Version 1 steht {"trophies":3,"car":"Red Racer"}. FromJson erstellt einen neuen RaceSave, wobei die Feldinitialisierungen ausgeführt werden, und setzt dann nur die Schlüssel, die im JSON enthalten sind. Daher ist musicVolume 0.8. 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 eine Initialisierung mit einem sinnvollen Wert hat.
JsonUtility.FromJsonOverwrite(json, obj) füllt ein bereits vorhandenes Objekt, statt eines zu erstellen, und lässt jedes Feld, das im JSON fehlt, unverändert. FromJson kann weder ein MonoBehaviour noch ein ScriptableObject erstellen (Unity gibt Cannot deserialize JSON to new instances of type 'RaceSettings.' aus). Ein Einstellungs-Asset wird daher geladen, indem es überschrieben wird: JsonUtility.FromJsonOverwrite(json, settings);. Beim Überschreiben bleiben außerdem die Werte erhalten, die ein Objekt bereits enthält, etwa die vom Inspector zugewiesenen Werte. FromJson würde dagegen die Initialisierungen der Klasse wiederherstellen.
Aufgabe
MittelLade pet.json sicher für neue Spieler und alte Spielstände.
- Ersetze in
Start()die FromJson-Zeile durchif (File.Exists(path))und einelse. - Wenn eine Datei vorhanden ist, fülle das Pet im Inspector:
JsonUtility.FromJsonOverwrite(File.ReadAllText(path), pet);, und protokolliere anschließendWelcome back, Mochiauspet.petName. - Wenn keine vorhanden ist, protokolliere auf dieselbe Weise
A new pet: Biscuit.
Drücke „Spielen“, füttere das Haustier, klicke dann auf Stop und wieder auf „Spielen“: Es heißt dich willkommen zurück. Klicke anschließend auf „Prüfen“.
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;
}
}
Alle Lektionen in Spielarchitektur in Unity
1Komponenten statt Hierarchien
Kleine KomponentenEin Basis-GegnerskriptAbstrakte KomponentenZusammenwirkende KomponentenRückblick: Modulares GeschützRückblick: Zwillingskanone4Serialisierte Daten
Serialisierbare KlassenListen im InspectorEnums im InspectorRückblick: Loot-TabelleRückblick: Beute auswürfeln2Schnittstellen in Unity
IDamageableSchnittstellen und TryGetComponentGetComponentsZusammenfassung: InteraktionstasteZusammenfassung: Nächstes in Reichweite5ScriptableObjects
Daten-AssetsWaffenwerteGemeinsame EinstellungenDen Wind speichernWellen als DatenRückblick: Item-DatenbankRückblick: Im Shop einkaufen8Wiederverwendbarer Code
ErweiterungsmethodenEin generisches SingletonGenerische HilfsmethodenRückblick: FindNearestÜbe selbstständig: Unity-Playground