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

Что такое десериализация?

1.3 Junior🔥 112 комментариев
#C# и ООП#Коллекции и структуры данных#Сеть и мультиплеер

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

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

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

Что такое десериализация?

Десериализация — это процесс преобразования данных из сериализованного формата (например, JSON, XML, бинарного потока) обратно в объект или структуру данных в памяти приложения. В контексте Unity и разработки игр это фундаментальная операция для сохранения и загрузки игрового состояния, конфигураций, сетевых сообщений или ресурсов.

Основные принципы и контекст использования

Десериализация неразрывно связана с сериализацией — процессом упаковки объекта в формат, пригодный для хранения или передачи. В Unity она используется повсеместно:

  • Сохранение игры: Загрузка прогресса игрока из файла JSON или бинарного формата.
  • Конфигурации: Чтение параметров уровней, баланса или настроек из XML/JSON-файлов.
  • Сетевое взаимодействие: Восстановление объектов из данных, полученных по сети (например, в Unity Netcode или Photon).
  • Ресурсы и ассеты: Загрузка скриптованных объектов (ScriptableObject) или пресетов.

Примеры десериализации в Unity

1. Десериализация JSON с помощью JsonUtility (встроенный инструмент Unity):

using UnityEngine;
using System;

[Serializable]
public class PlayerData
{
    public string playerName;
    public int level;
    public float health;
}

public class JsonExample : MonoBehaviour
{
    void Start()
    {
        // Сериализованная строка JSON (например, из файла)
        string jsonString = "{\"playerName\":\"Hero\",\"level\":10,\"health\":85.5}";

        // Процесс десериализации
        PlayerData loadedData = JsonUtility.FromJson<PlayerData>(jsonString);

        // Теперь объект loadedData содержит восстановленные данные
        Debug.Log($"Name: {loadedData.playerName}, Level: {loadedData.level}");
        // Вывод: Name: Hero, Level: 10
    }
}

2. Десериализация с использованием Newtonsoft.Json (более гибкая сторонняя библиотека, популярная до версий Unity 2023+):

using Newtonsoft.Json;
using System.Collections.Generic;

public class InventoryManager : MonoBehaviour
{
    [System.Serializable]
    public class InventoryItem
    {
        public string id;
        public int count;
    }

    void LoadInventory()
    {
        string jsonFromServer = "[{\"id\":\"sword\",\"count\":1},{\"id\":\"potion\",\"count\":5}]";
        
        // Десериализация списка объектов
        List<InventoryItem> inventory = JsonConvert.DeserializeObject<List<InventoryItem>>(jsonFromServer);
        
        foreach (var item in inventory)
        {
            Debug.Log($"Item: {item.id}, Count: {item.count}");
        }
    }
}

Ключевые аспекты и подводные камни

  • Производительность: Частая десериализация больших данных (например, полного состояния мира) может вызывать просадки FPS. Рекомендуется выполнять её асинхронно или в фоновых потоках.
  • Безопасность: Десериализация данных из ненадёжных источников (например, от игроков в мультиплеере) — это риск безопасности. Злоумышленник может передать вредоносные данные, вызывающие переполнение памяти или выполнение кода. Всегда валидируйте входные данные.
  • Совместимость: Изменение структуры класса после сериализации данных (удаление/переименование полей) может сломать десериализацию. Используйте атрибуты [SerializeField], [JsonIgnore] или резервные методы миграции данных.
  • Типизация: В отличие от сериализации, при десериализации необходимо знать целевой тип объекта. Динамическую десериализацию (когда тип неизвестен заранее) можно реализовать через кастомные конвертеры или поля-дискриминаторы.

Альтернативные форматы и инструменты в Unity

  • BinaryFormatter (System.Runtime.Serialization.Formatters.Binary): Мощный, но устаревший и небезопасный инструмент. Не рекомендуется к использованию из-за уязвимостей.
  • XML (System.Xml.Serialization): Читаем для человека, но более объёмный и медленный, чем JSON.
  • Protocol Buffers (например, через Google.Protobuf): Эффективный бинарный формат для сетевых коммуникаций с минимальным размером данных.
  • Unity Serialization (продвинутая система, используемая для ScriptableObject и префабов): Работает через движок Unity, требует особой обработки для кастомных типов.

Практические рекомендации

  • Для простых данных используйте JsonUtility — он интегрирован в Unity и достаточно быстр.
  • Для сложных структур с полиморфизмом, словарями или кастомными правилами выберите Newtonsoft.Json (чесли Package Manager) или Unity.SerializeReference.
  • Всегда обрабатывайте исключения при десериализации (JsonException, ArgumentNullException).
  • В мультиплеере используйте инкрементную десериализацию — загружайте только изменённые данные, а не полное состояние.

Десериализация — это мост между персистентным хранением и runtime-логикой. Понимание её принципов позволяет создавать устойчивые, производительные системы сохранений, конфигураций и сетевого кода, что критически важно для современных игр на Unity.