← Назад к вопросам

Какие знаешь способы сохранения игры?

1.6 Junior🔥 132 комментариев
#Unity Core#Ресурсы и ассеты

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Способы сохранения игры в Unity

В Unity существует несколько основных подходов к сохранению игрового прогресса, каждый со своими преимуществами, недостатками и сценариями применения.

1. PlayerPrefs (Пользовательские настройки)

Самый простой, встроенный в Unity способ хранения простых данных. По сути, это ключ-значение хранилище, которое записывает данные в реестр (Windows) или plist-файлы (macOS/iOS).

  • Преимущества: Очень прост в использовании, не требует дополнительных библиотек, подходит для настроек (громкость, качество графики).
  • Недостатки: Ненадёжен для сложных данных, легко редактируется пользователем, ограничен по объёму.
  • Использование:
// Запись
PlayerPrefs.SetInt("PlayerScore", 100);
PlayerPrefs.SetString("PlayerName", "Hero");
PlayerPrefs.SetFloat("MusicVolume", 0.75f);
PlayerPrefs.Save(); // Явное сохранение на диск

// Чтение
int score = PlayerPrefs.GetInt("PlayerScore", 0); // 0 - значение по умолчанию

2. Сериализация в бинарный или текстовый формат

Наиболее распространённый и гибкий подход. Заключается в преобразовании состояния игровых объектов в поток данных (байты или текст) и записи в файл. Основные инструменты:

  • Бинарная сериализация (System.Runtime.Serialization.Formatters.Binary): Компактный и быстрый формат, но данные нечитаемы для человека и могут быть нестабильны между версиями игры.
  • JSON (Newtonsoft.Json или UnityEngine.JsonUtility): Текстовый, человекочитаемый формат. JsonUtility отлично работает с классами, помеченными как [System.Serializable], но имеет ограничения (например, не сериализует словари). Для сложных случаев используют библиотеку Newtonsoft Json.NET.
  • XML (System.Xml.Serialization): Структурированный текстовый формат, но более громоздкий, чем JSON.
using System.IO;
using UnityEngine;

[System.Serializable]
public class SaveData
{
    public Vector3 playerPosition;
    public int health;
    public string[] inventoryItems;
}

public class SaveManager : MonoBehaviour
{
    public void SaveGame(SaveData data)
    {
        // Использование JsonUtility
        string json = JsonUtility.ToJson(data, true); // true для красивого форматирования
        string path = Path.Combine(Application.persistentDataPath, "savegame.json");
        File.WriteAllText(path, json);
        Debug.Log($"Game saved to: {path}");
    }

    public SaveData LoadGame()
    {
        string path = Path.Combine(Application.persistentDataPath, "savegame.json");
        if (File.Exists(path))
        {
            string json = File.ReadAllText(path);
            return JsonUtility.FromJson<SaveData>(json);
        }
        return null;
    }
}

3. Фреймворки и ассеты

Для профессиональных проектов часто используют готовые решения:

  • Odin Serializer: Мощный сериализатор, поддерживающий почти все типы данных C#.
  • Easy Save 3: Популярный ассет из Asset Store, предоставляющий простой API, шифрование, работу с облаком.
  • JSON.NET (Newtonsoft.Json): Де-факто стандарт для работы с JSON в .NET, требует ручной интеграции.

4. Работа с файловой системой напрямую (System.IO)

Используется для нестандартных задач: сохранения скриншотов, пользовательских уровней, логирования. Основные классы: File, StreamWriter, BinaryWriter.

5. Сетевое/облачное сохранение

Для мультиплатформенности или защиты от потери данных (например, в мобильных играх).

  • Unity Cloud Save (часть Unity Gaming Services): Готовое облачное решение от Unity.
  • Собственный бэкенд (REST API + база данных): Полный контроль, но требует навыков серверной разработки.
  • Сторонние сервисы: PlayFab, Firebase Realtime Database.

6. Сохранение через ScriptableObject

ScriptableObject может выступать в роли контейнера постоянных данных (настройки игры, статы предметов). Однако для игрового прогресса их используют редко, так как данные в них сохраняются только в редакторе, а в билде — остаются неизменными после записи.


Ключевые принципы и лучшие практики:

  • Путь для сохранения: Всегда используйте Application.persistentDataPath — это кроссплатформенный путь, куда приложение имеет право записи.
  • Структура данных: Разрабатывайте отдельный, чётко структурированный класс для всех данных сохранения (SaveData).
  • Инкапсуляция логики: Выделяйте сохранение/загрузку в отдельный менеджер (SaveManager).
  • Обработка ошибок: Всегда оборачивайте операции с файлами в try-catch блоки.
  • Резервное копирование: Перед перезаписью создавайте копию старого файла сохранения.
  • Версионность данных: Включайте поле saveVersion в класс сохранения, чтобы при обновлении игры можно было конвертировать старые сохранения в новый формат.
  • Производительность: Для больших объёмов данных (например, карта мира) используйте инкрементальное сохранение или сегментирование (сохранение по частям).

Выбор метода зависит от сложности проекта. Для прототипа или гипер-казуальной игры хватит PlayerPrefs. Для полноценной RPG с инвентарём, квестами и миром нужна сериализация в JSON или бинарный формат с шифрованием. Для онлайн-игры с синхронизацией прогресса между устройствами необходим облачный бэкенд.