AssetBundle — управление ассетами

AssetBundle

AssetBundle — это контейнер для сохранения иерархических данных игровых объектов с поддержкой типов, ссылок и сжатия.

Основные операции

Добавление объектов

var bundle = new AssetBundle();

// Сериализовать объект (использует его GUID)
var player = new GameObject();
bundle.Serialize(player);

// С явным GUID
bundle.Serialize(myGuid, someObject);

// Попытка добавить (не перезапишет существующий)
if (bundle.TryAdd(block)) { /* успех */ }

Доступ и удаление

// Получить по GUID
var block = bundle[guid];

// Удалить
bundle.Remove(guid);

// Очистить всё
bundle.Clear();

// Информация
int count = bundle.Length;
IEnumerable<Guid> allGuids = bundle.Guids;

Сохранение и загрузка

AssetBundle работает исключительно с объектами в памяти. Для преобразования в текстовый или бинарный формат используйте интерфейс IAssetBundleSerializer:

var bundle = new AssetBundle();
bundle.Serialize(player);

// Выбрать сериализатор
var serializer = new AssetBundleJsonSerializer(prettyPrint: true);

// Получить байты
byte[] data = serializer.Serialize(bundle);

// Сохранить на диск
await File.WriteAllBytesAsync("bundle.json", data);

// Загрузить с диска
byte[] loadedData = await File.ReadAllBytesAsync("bundle.json");
var loadedBundle = serializer.Deserialize(loadedData);

Типы и регистрация

AssetBundle автоматически регистрирует типы при сериализации:

public class Character : GameObject
{
    [SerializableField]
    public string Name { get; set; }
    
    [SerializableField]
    public int Health { get; set; }
    
    [SerializableField]
    public List<Item> Inventory { get; set; } = new();
}

public class Item : GameObject
{
    [SerializableField]
    public string ItemName { get; set; }
    
    [SerializableField]
    public int Quantity { get; set; }
}

// Регистрируются автоматически
var bundle = new AssetBundle();
var character = new Character { Name = "Hero", Health = 100 };
character.Inventory.Add(new Item { ItemName = "Sword", Quantity = 1 });
bundle.Serialize(character);

// Типы доступны в bundle.Types
var characterType = bundle.Types["Character"];

Ссылки между объектами

Для ссылок между объектами в AssetBundle используйте IReference:

// При сериализации используются автоматические ссылки
var character = new Character { Name = "Elder" };
var quest = new Quest { Questgiver = character };

var bundle = new AssetBundle();
bundle.Serialize(character);
bundle.Serialize(quest);

// Ссылки восстанавливаются автоматически при десериализации

Сжатие и сериализация

Доступные сериализаторы

1. AssetBundleJsonSerializer — JSON формат

Читаемый текстовый формат, подходит для конфигураций и веб-обмена.

var serializer = new AssetBundleJsonSerializer(prettyPrint: true);
byte[] data = serializer.Serialize(bundle);
var loaded = serializer.Deserialize(data);

2. AssetBundleXmlSerializer — XML формат

Структурированный формат с поддержкой древовидных структур.

var serializer = new AssetBundleXmlSerializer(SaveOptions.None);
byte[] data = serializer.Serialize(bundle);
var loaded = serializer.Deserialize(data);

3. AssetBundleYamlSerializer — YAML формат

Человеко-ориентированный формат, удобен для конфигураций.

var serializer = new AssetBundleYamlSerializer();
byte[] data = serializer.Serialize(bundle);
var loaded = serializer.Deserialize(data);

4. AssetBundleBinarySerializer — Бинарный формат

Компактный и быстрый формат, не требует парсинга.

var serializer = new AssetBundleBinarySerializer();
byte[] data = serializer.Serialize(bundle);
var loaded = serializer.Deserialize(data);

5. AssetBundleCompressedSerializer — Сжатый бинарный формат

Оборачивает другой сериализатор с поддержкой сжатия (Deflate, GZip, LZMA).

var compressedSerializer = new AssetBundleCompressedSerializer(
    level: CompressionLevel.Optimal,
    method: CompressionMethod.Deflate
);

byte[] compressed = compressedSerializer.Serialize(bundle);
var loaded = compressedSerializer.Deserialize(compressed);

6. AssetBundleEncryptedSerializer — Шифрованный формат

Оборачивает другой сериализатор с поддержкой AES шифрования.

byte[] key = EncryptionHelper.AesGenerateKey(32);
byte[] iv = EncryptionHelper.AesGenerateIV();

var encryptedSerializer = new AssetBundleEncryptedSerializer(
    key: key,
    iv: iv,
    level: CompressionLevel.Optimal,
    method: CompressionMethod.Deflate
);

byte[] encrypted = encryptedSerializer.Serialize(bundle);
var loaded = encryptedSerializer.Deserialize(encrypted);

7. AssetBundlePropertySerializer — Properties формат (key=value)

Простой текстовый формат для плоских структур данных.

var serializer = new AssetBundlePropertySerializer();
byte[] data = serializer.Serialize(bundle);
var loaded = serializer.Deserialize(data);

Комбинирование сериализаторов

Вы можете комбинировать сериализаторы для достижения нужного результата:

// Бинарный + сжатие + шифрование
var key = EncryptionHelper.AesGenerateKey(32);
var iv = EncryptionHelper.AesGenerateIV();

var encrypted = new AssetBundleEncryptedSerializer(
    key: key,
    iv: iv,
    level: CompressionLevel.Optimal
);

// Сериализовать и сохранить
byte[] data = encrypted.Serialize(bundle);
await File.WriteAllBytesAsync("bundle.secured", data);

Практические примеры

Сохранение сцены

public class Scene : GameObject
{
    [SerializableField]
    public string SceneName { get; set; }
    
    [SerializableField]
    public List<GameObject> GameObjects { get; set; } = new();
}

// Создать сцену с объектами
var scene = new Scene { SceneName = "Level1" };
var player = new GameObject();
var enemy = new GameObject();
scene.GameObjects.AddRange(new[] { player, enemy });

// Сохранить в AssetBundle
var bundle = new AssetBundle();
bundle.Serialize(scene);
bundle.Serialize(player);
bundle.Serialize(enemy);

// Использовать JSON сериализатор
var serializer = new AssetBundleJsonSerializer(prettyPrint: true);
byte[] data = serializer.Serialize(bundle);
await File.WriteAllBytesAsync("level1.json", data);

// Загрузить
byte[] loadedData = await File.ReadAllBytesAsync("level1.json");
var loaded = serializer.Deserialize(loadedData);
var sceneData = loaded[scene.GUID] as Scene;
Console.WriteLine($"Loaded scene: {sceneData.SceneName}");

Пакетный импорт ассетов

var bundle = new AssetBundle();
var serializer = new AssetBundleJsonSerializer();

// Загрузить множество ассетов из JSON файлов
foreach (var assetFile in Directory.GetFiles("assets/", "*.json"))
{
    var json = await File.ReadAllTextAsync(assetFile);
    var data = Encoding.UTF8.GetBytes(json);
    var loadedBundle = serializer.Deserialize(data);
    
    // Объединить в общий пакет
    foreach (var guid in loadedBundle.Guids)
    {
        bundle.TryAdd(loadedBundle[guid]);
    }
}

// Сохранить всё в один файл с сжатием
var compressedSerializer = new AssetBundleCompressedSerializer(
    CompressionLevel.Optimal
);
byte[] packed = compressedSerializer.Serialize(bundle);
await File.WriteAllBytesAsync("assets.igb", packed);

© 2026 Igdrasil Project. Все права защищены.