Menu
CoddyTech

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.

challenge icon

Aufgabe

Mittel

Das 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 protokolliere A new pet: Biscuit.
  • In Version 1 des Spiels wurden nur petName und hunger gespeichert; happiness und toys kamen 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 mit JsonUtility.FromJsonOverwrite in pet, damit Werte, die in der Datei fehlen, den Wert aus dem Inspector beibehalten, und protokolliere die Begrüßung mit dem geladenen Namen, also Welcome 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;
    }
}
quiz iconTeste dich selbst

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