Menu
CoddyTech

Загрузка и значения по умолчанию

Часть раздела Архитектура игр в Unity путешествия по Unity на Coddy. Урок 32 из 64.

Загрузка должна обрабатывать сохранения, которых нет или которые заполнены не полностью. Гоночная игра сохраняет RaceSave; во второй версии игры было добавлено 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();
}

У нового игрока нет файла, а File.ReadAllText для отсутствующего файла вызывает исключение FileNotFoundException, поэтому сначала проверьте File.Exists, а затем начните с new RaceSave(): 0 трофеев, Rookie Kart и громкость 0.8 — значения инициализаторов полей. В файле версии 1 старого игрока содержится {"trophies":3,"car":"Red Racer"}. FromJson создаёт новый RaceSave, при этом выполняются инициализаторы полей, а затем задаются только те ключи, которые есть в JSON, поэтому значение musicVolume равно 0.8. Ключ, для которого в классе нет поля, игнорируется. Поэтому новая версия игры может читать старые сохранения, если каждому новому полю присвоено разумное начальное значение.

JsonUtility.FromJsonOverwrite(json, obj) заполняет уже существующий объект вместо создания нового и оставляет без изменений все поля, которых нет в JSON. FromJson не может создать MonoBehaviour или ScriptableObject (Unity выдаёт исключение Cannot deserialize JSON to new instances of type 'RaceSettings.'), поэтому ресурс настроек загружается путём перезаписи: JsonUtility.FromJsonOverwrite(json, settings);. Перезапись также сохраняет значения, которые уже есть в объекте, например заданные ему в Inspector; FromJson вместо этого восстановил бы начальные значения класса.

challenge icon

Задание

Средне

Безопасно загружай pet.json для новых игроков и из старых сохранений.

  1. В Start() замени строку FromJson на if (File.Exists(path)) и добавь else.
  2. Если файл есть, заполни pet в Inspector: JsonUtility.FromJsonOverwrite(File.ReadAllText(path), pet);, а затем выведи в журнал Welcome back, Mochi из pet.petName.
  3. Если файла нет, таким же способом выведи в журнал A new pet: Biscuit.

Нажми «Играть», покорми питомца, затем нажми «Стоп» и снова «Играть»: появится сообщение о возвращении. Затем нажми «Проверить».

Попробуйте сами

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

Все уроки раздела Архитектура игр в Unity

Потренируйтесь самостоятельно: Песочница Unity