Menu
CoddyTech

Caricamento e valori predefiniti

Fa parte della sezione Architettura dei giochi in Unity del percorso Unity di Coddy. Lezione 32 di 64.

Il caricamento deve poter gestire salvataggi mancanti o incompleti. Un gioco di corse salva un RaceSave; la versione 2 del gioco ha aggiunto musicVolume:

[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();
}

Un nuovo giocatore non ha alcun file e File.ReadAllText genera un'eccezione FileNotFoundException se il file non esiste, quindi controlla prima File.Exists e parti da new RaceSave(): 0 trofei, la Rookie Kart e volume 0.8, cioè gli inizializzatori dei campi. Il file della versione 1 di un vecchio giocatore contiene {"trophies":3,"car":"Red Racer"}. FromJson crea un nuovo RaceSave, esegue gli inizializzatori dei campi e poi imposta solo le chiavi presenti nel JSON, quindi musicVolume è 0.8. Una chiave per cui la classe non ha un campo viene ignorata. Una nuova versione del gioco può quindi leggere i vecchi salvataggi, purché ogni nuovo campo abbia un inizializzatore con un valore sensato.

JsonUtility.FromJsonOverwrite(json, obj) riempie un oggetto già esistente invece di crearne uno e lascia invariati tutti i campi assenti dal JSON. FromJson non può creare un MonoBehaviour o uno ScriptableObject (Unity genera l'eccezione Cannot deserialize JSON to new instances of type 'RaceSettings.'), quindi una risorsa delle impostazioni viene caricata sovrascrivendola: JsonUtility.FromJsonOverwrite(json, settings);. La sovrascrittura mantiene anche i valori già presenti nell'oggetto, per esempio quelli assegnati dall'Inspector, mentre FromJson ripristinerebbe gli inizializzatori della classe.

challenge icon

Sfida

Medio

Carica pet.json in modo sicuro per i nuovi giocatori e per i vecchi salvataggi.

  1. In Start(), sostituisci la riga FromJson con if (File.Exists(path)) e un else.
  2. Se è presente un file, compila pet nell'Inspector: JsonUtility.FromJsonOverwrite(File.ReadAllText(path), pet);, poi registra Welcome back, Mochi da pet.petName.
  3. Se non è presente, registra A new pet: Biscuit allo stesso modo.

Premi «Gioca», dai da mangiare all'animale, poi premi Stop e «Gioca»: ti dà il bentornato. Poi premi «Verifica».

Provalo tu

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;
    }
}

Tutte le lezioni di Architettura dei giochi in Unity

Esercitati da solo: Playground Unity