Загрузка и значения по умолчанию
Часть раздела Архитектура игр в 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 вместо этого восстановил бы начальные значения класса.
Задание
СреднеБезопасно загружай pet.json для новых игроков и из старых сохранений.
- В
Start()замени строку FromJson наif (File.Exists(path))и добавьelse. - Если файл есть, заполни pet в Inspector:
JsonUtility.FromJsonOverwrite(File.ReadAllText(path), pet);, а затем выведи в журналWelcome back, Mochiизpet.petName. - Если файла нет, таким же способом выведи в журнал
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
1Компоненты, а не иерархии
Небольшие компонентыБазовый скрипт врагаАбстрактные компонентыКомпоненты работают вместеПовторение: модульная турельПовторение: спаренная пушка4Сериализованные данные
Сериализуемые классыСписки в инспектореПеречисления в инспектореПовторение: таблица добычиПовторение: определяем добычу2Интерфейсы в Unity
IDamageableИнтерфейсы и TryGetComponentGetComponentsПовторение: клавиша взаимодействияПовторение: ближайший в пределах досягаемости5ScriptableObjects
Ресурсы данныхХарактеристики оружияОбщие настройкиСохраняем ветерВолны как данныеПовторение: база предметовПовторение: покупка в магазине3События
События C# в UnityПодписка в OnEnableПоля UnityEventСобытия управляют UIПовторение: всплывающее окно достиженияПовторение: таймер всплывающего окна6Сохранение с помощью JSON
JsonUtilityСохранение игрыЗагрузка и значения по умолчаниюПовторение: слоты сохраненияВыбор и удаление слотаПотренируйтесь самостоятельно: Песочница Unity