Menu
CoddyTech

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.

challenge icon

Aufgabe

Mittel

Lade pet.json sicher für neue Spieler und alte Spielstände.

  1. Ersetze in Start() die FromJson-Zeile durch if (File.Exists(path)) und ein else.
  2. Wenn eine Datei vorhanden ist, fülle das Pet im Inspector: JsonUtility.FromJsonOverwrite(File.ReadAllText(path), pet);, und protokolliere anschließend Welcome back, Mochi aus pet.petName.
  3. 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

Übe selbstständig: Unity-Playground