Сохранение игры
Часть раздела Архитектура игр в Unity путешествия по Unity на Coddy. Урок 25 из 50.
Сохранение игры — это один объект, записанный в формате JSON. Помести всё необходимое для сохранения в класс [System.Serializable], заполни его данными из игры и запиши результат JsonUtility.ToJson в место, которое сохраняется после завершения игры. В этом подземелье сохраняются этаж, золото и найденные ключи:
[System.Serializable]
public class DungeonSave
{
public int floor;
public int gold;
public List<string> keys;
}using System.Collections.Generic;
using System.IO;
using UnityEngine;
public class Dungeon : MonoBehaviour
{
public int floor = 1;
public int gold;
public List<string> keys = new List<string>();
private string path;
void Start()
{
path = Path.Combine(Application.persistentDataPath, "dungeon.json");
if (File.Exists(path))
{
DungeonSave save = JsonUtility.FromJson<DungeonSave>(File.ReadAllText(path));
floor = save.floor;
gold = save.gold;
keys = save.keys;
}
}
public void Save()
{
DungeonSave save = new DungeonSave();
save.floor = floor;
save.gold = gold;
save.keys = keys;
File.WriteAllText(path, JsonUtility.ToJson(save));
}
}Application.persistentDataPath — это папка, которую Unity предоставляет игре на каждой платформе; она сохраняется между запусками игры и при обновлениях. Path.Combine соединяет её с именем файла, используя разделитель, принятый на платформе. File.WriteAllText(path, text) записывает файл, заменяя старый, File.Exists сообщает, существует ли такой файл, а File.ReadAllText считывает его содержимое (все три метода — из System.IO). Папка самой игры может быть доступна только для чтения, поэтому сохранения помещаются в persistentDataPath и никуда больше. Создавай путь в Awake или Start: Unity не разрешает использовать persistentDataPath при инициализации поля.
Класс сохранения содержит только то, что нужно сохранить, а игра копирует в него значения для сохранения и из него — для загрузки. Небольшое сохранение можно поместить в PlayerPrefs вместо файла: PlayerPrefs.SetString("dungeon", json) и PlayerPrefs.GetString("dungeon") хранят тот же JSON. Сохраняй игру, когда происходит что-то важное, на контрольной точке или с помощью кнопки сохранения: OnApplicationQuit выполняется при обычном выходе, но телефон может закрыть игру в фоновом режиме без вызова этого метода.
Задание
СреднеИсследователь ходит по острову с помощью стрелок, а клавиша Space устанавливает флаг там, где стоит исследователь. Сохраните игру на острове в файле island.json:
- В
IslandSave.csнапишите класс[System.Serializable]IslandSaveс открытыми полямиplayerPosition(типа Vector3) иflags(типаList<Vector3>). - Метод
Save(), который вызывает кнопка Save, записывает позицию исследователя и флаги в формате JSON в файлisland.jsonвApplication.persistentDataPath. - В
Start(), если существуетisland.json, верните исследователя в сохранённую позицию и снова установите все сохранённые флаги с помощьюPlantFlag, чтобы флаги попали в список для следующего сохранения.
Нажмите Play, установите несколько флагов и нажмите Save, затем нажмите Stop и снова Play. После этого нажмите Check.
Попробуйте сами
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.InputSystem;
public class Explorer : MonoBehaviour
{
public GameObject flagPrefab;
public float speed = 4f;
private List<Vector3> flags = new List<Vector3>();
private InputAction moveAction;
void Start()
{
moveAction = InputSystem.actions.FindAction("Move");
// Загрузите island.json здесь
}
void Update()
{
Vector2 input = moveAction.ReadValue<Vector2>();
transform.Translate(new Vector3(input.x, 0f, input.y) * speed * Time.deltaTime);
if (Keyboard.current.spaceKey.wasPressedThisFrame)
{
PlantFlag(transform.position);
}
}
void PlantFlag(Vector3 position)
{
flags.Add(position);
Instantiate(flagPrefab, new Vector3(position.x, 0.5f, position.z), Quaternion.identity);
}
// Кнопка Save вызывает этот метод
public void Save()
{
// Запишите позицию игрока и флаги в island.json
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Архитектура игр в Unity
1Компоненты, а не иерархии
Небольшие компонентыБазовый скрипт врагаАбстрактные компонентыСовместная работа компонентовПовторение: модульная турель4Сериализованные данные
Сериализуемые классыСписки в InspectorПеречисления в InspectorПовторение: таблица лута2Интерфейсы в Unity
IDamageableИнтерфейсы и TryGetComponentGetComponentsПовторение: клавиша взаимодействия5ScriptableObjects
Ресурсы данныхХарактеристики оружияОбщие настройкиВолны как данныеПовторение: база предметов3События
События C# в UnityПодписка в OnEnableПоля UnityEventСобытия управляют интерфейсомПовторение: всплывающее окно достижения6Сохранение с помощью JSON
JsonUtilityСохранение игрыЗагрузка и значения по умолчаниюПовторение: слоты сохранения