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

Как сохранять и загружать данные в Unity? Какие способы сериализации вы знаете?

1.7 Middle🔥 191 комментариев
#Unity Core

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

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

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

Сохранение и загрузка данных в Unity

Сохранение и загрузка данных — критически важная функция для большинства игр, позволяющая сохранять прогресс, настройки и состояние игры. В Unity существует несколько подходов, каждый со своими преимуществами и ограничениями. Рассмотрим основные методы и способы сериализации.

Основные подходы к сохранению данных

1. PlayerPrefs Идеально подходит для простых данных: настроек, рекордов, небольших значений. Хранит данные в реестре (Windows) или plist-файлах (macOS/iOS).

// Сохранение
PlayerPrefs.SetInt("HighScore", 1000);
PlayerPrefs.SetString("PlayerName", "Alex");
PlayerPrefs.SetFloat("Volume", 0.75f);
PlayerPrefs.Save(); // Явное сохранение

// Загрузка
int score = PlayerPrefs.GetInt("HighScore", 0); // 0 - значение по умолчанию
string name = PlayerPrefs.GetString("PlayerName");
float volume = PlayerPrefs.GetFloat("Volume", 1.0f);

Преимущества: простой API, кроссплатформенность. Недостатки: ограниченные типы данных (int, float, string), небезопасно (данные могут быть изменены пользователем).

2. Бинарная сериализация в файлы Наиболее гибкий подход для сложных структур данных. Использует потоковую запись в файлы.

using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

[System.Serializable]
public class GameData
{
    public int level;
    public float health;
    public Vector3 position;
    public List<string> inventory;
}

public void SaveBinary(GameData data, string filename)
{
    BinaryFormatter formatter = new BinaryFormatter();
    FileStream stream = new FileStream(Application.persistentDataPath + "/" + filename, FileMode.Create);
    formatter.Serialize(stream, data);
    stream.Close();
}

public GameData LoadBinary(string filename)
{
    string path = Application.persistentDataPath + "/" + filename;
    if (File.Exists(path))
    {
        BinaryFormatter formatter = new BinaryFormatter();
        FileStream stream = new FileStream(path, FileMode.Open);
        GameData data = formatter.Deserialize(stream) as GameData;
        stream.Close();
        return data;
    }
    return null;
}

Внимание: BinaryFormatter считается небезопасным и устаревшим в современных версиях .NET. Рекомендуется использовать альтернативные методы сериализации.

3. JSON сериализация Современный, читаемый и кроссплатформенный формат. Unity поддерживает JsonUtility (встроенный) и Newtonsoft.Json (сторонний пакет).

using UnityEngine;

[System.Serializable]
public class PlayerData
{
    public string playerName;
    public int experience;
    public Vector3 lastPosition;
}

// Использование JsonUtility
public void SaveJson(PlayerData data, string filename)
{
    string json = JsonUtility.ToJson(data, true); // true для красивого форматирования
    File.WriteAllText(Application.persistentDataPath + "/" + filename, json);
}

public PlayerData LoadJson(string filename)
{
    string path = Application.persistentDataPath + "/" + filename;
    if (File.Exists(path))
    {
        string json = File.ReadAllText(path);
        return JsonUtility.FromJson<PlayerData>(json);
    }
    return new PlayerData();
}

4. XML сериализация Человекочитаемый формат с возможностью ручного редактирования, но более объемный чем JSON.

using System.Xml.Serialization;

public void SaveXML(object data, string filename)
{
    XmlSerializer serializer = new XmlSerializer(data.GetType());
    StreamWriter writer = new StreamWriter(Application.persistentDataPath + "/" + filename);
    serializer.Serialize(writer, data);
    writer.Close();
}

Ключевые способы сериализации

  • Бинарная сериализация

    • Максимальная производительность
    • Наименьший размер файлов
    • Нечитаемый формат (безопасность)
    • Проблемы с версионностью данных
  • JSON сериализация

    • Человекочитаемый формат
    • Кроссплатформенность
    • Широкая поддержка в различных языках
    • Немного медленнее бинарной
    • Идеально для конфигураций и сохранений
  • XML сериализация

    • Структурированный, самодокументируемый формат
    • Поддержка схем (XSD)
    • Большой объем файлов
    • Сложнее в обработке чем JSON

Современные best practices

Используйте Application.persistentDataPath для получения корректного пути на всех платформах:

  • Windows: %AppData%/../LocalLow/<CompanyName>/<ProductName>
  • Android: /data/data/<package>/files
  • iOS: Application/Data/<AppName>/Documents

Шифруйте чувствительные данные:

using System.Security.Cryptography;
using System.Text;

public string EncryptData(string plainText, string key)
{
    // Реализация шифрования (AES, XOR для простоты)
    byte[] bytes = Encoding.UTF8.GetBytes(plainText);
    // ... алгоритм шифрования
    return Convert.ToBase64String(encryptedBytes);
}

Реализуйте систему версионности данных:

[System.Serializable]
public class SaveGame
{
    public int version = 2; // Текущая версия формата
    public PlayerData playerData;
    // При загрузке старой версии можно выполнить миграцию данных
}

Рассмотрите ScriptableObject для хранения неизменяемых конфигурационных данных, которые редактируются в редакторе Unity.

Рекомендации

  • Для простых данных используйте PlayerPrefs
  • Для сложных структур — JSON сериализацию (JsonUtility или Newtonsoft.Json)
  • Избегайте BinaryFormatter в новых проектах
  • Всегда проверяйте существование файлов перед загрузкой
  • Реализуйте обработку ошибок при чтении/записи
  • Для облачных сохранений используйте соответствующие API платформ (Play Games Services, Game Center, Steam Cloud)

Правильный выбор метода зависит от типа данных, требований к производительности, безопасности и необходимости редактирования данных вне игры. В современных проектах JSON стал де-факто стандартом для большинства задач сохранения игрового состояния.