Addressables — современная загрузка ассетов
Асинхронная загрузка по адресу, замена Resources.Load и AssetBundles.
В Unity исторически есть несколько способов загрузить ассет в рантайме: Resources.Load,
AssetBundles, и Addressables (com.unity.addressables). Последний — рекомендованный современный
путь, и в новых проектах остальные стоит избегать.
Что не так с Resources.Load
Resources.Load<Texture>("MyTexture") — простой API: достаёте ассет из папки Resources/ по пути.
Звучит удобно, но:
- Всё в Resources попадает в билд целиком. Любой ассет в
Resources/Unity упаковывает даже если он не используется на текущей сцене. Резко раздувает размер билда. - Нет асинхронной загрузки из коробки.
Resources.LoadAsyncесть, но не решает первую проблему. - Нет управления версиями. Не можно обновить пакет ассетов отдельно от билда.
Unity сама в документации пишет: “We recommend not using the Resources folder.”
Идея Addressables
Каждому ассету (или группе) присваивается address — строковый ключ. Загружаете по этому ключу асинхронно. Где физически лежит ассет — в локальном билде, на удалённом CDN, в общем bundle с другими — определяется конфигом, а не кодом. Можно обновить группу ассетов на CDN, и игроки получат новые версии без редеплоя билда.
Code splitting + dynamic import + CDN. Вы вызываете import('./module-heavy') — браузер
подгружает chunk по сети. У вас один билд, тяжёлые модули отделены и грузятся по требованию.
Addressables.LoadAssetAsync<GameObject>("EnemyBoss") — Unity находит, в каком bundle лежит ассет,
загружает (с диска или с CDN), возвращает handle. Используете → освобождаете.
Настройка
- Установите пакет
com.unity.addressablesчерез Package Manager. - Window → Asset Management → Addressables → Groups — откроется окно с группами.
- Выберите ассет в Project, в Inspector поставьте галочку Addressable. По умолчанию address =
путь к ассету; смените на короткое имя, например
EnemyBoss. - Группа — это контейнер ассетов с общими настройками сборки (local/remote, compression, …).
Загрузка в коде
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
public class BossSpawner : MonoBehaviour
{
[SerializeField] private AssetReferenceGameObject bossRef;
private GameObject _bossInstance;
public async void SpawnBoss() {
// Загружаем GameObject prefab асинхронно
AsyncOperationHandle<GameObject> handle = bossRef.LoadAssetAsync<GameObject>();
await handle.Task;
if (handle.Status == AsyncOperationStatus.Succeeded) {
_bossInstance = Instantiate(handle.Result, transform.position, Quaternion.identity);
}
}
private void OnDestroy() {
// ВАЖНО: освобождаем загруженный ассет, чтобы он мог быть выгружен
if (bossRef.IsValid()) {
bossRef.ReleaseAsset();
}
}
}
AssetReference — тип поля для Inspector. Перетягиваете в него Addressable-ассет, и в Inspector
получаете dropdown выбора. Это типизированно и удобнее, чем строки.
Можно и по строке, если address известен:
AsyncOperationHandle<Sprite> handle = Addressables.LoadAssetAsync<Sprite>("UI/Icons/Coin");
await handle.Task;
icon.sprite = handle.Result;
InstantiateAsync — сразу спавн
Часто нужно не “загрузить ассет, потом Instantiate”, а сразу создать инстанс. Есть short-cut:
AsyncOperationHandle<GameObject> handle = Addressables.InstantiateAsync("EnemyBoss", spawnPos, Quaternion.identity);
await handle.Task;
GameObject boss = handle.Result;
// Когда босс убит:
Addressables.ReleaseInstance(boss); // освобождает И ассет, И уничтожает GameObject
Каждому Load (или InstantiateAsync) нужен Release. Не освобождаете — ассет остаётся в памяти на весь жизненный цикл приложения. Это самый частый источник утечек в проектах на Addressables.
Группы и профили
В Addressables Groups вы группируете ассеты по логике — например, “WorldStreaming”, “UI”, “DLC_Level1”. Каждой группе задаются настройки:
- Build Path / Load Path — где собирается и откуда грузится bundle (локально / по URL).
- Compression — LZ4 (быстро) / LZMA (компактно) / Uncompressed.
- Bundle Mode — Pack Together / Pack Separately / Pack Together by Label.
Profiles — это наборы переменных ({LOCAL_BUILD_PATH}, {REMOTE_LOAD_PATH}). Удобно для
переключения “Editor / Test / Production” одним кликом.
Remote Content и Content Update
Главный плюс Addressables — обновление контента без обновления билда. Сценарий:
- Группа “Levels_DLC1” собирается в bundle с Build Path = удалённый CDN.
- При запуске игра обращается к catalog (json с описанием версий bundle’ов).
- Если каталог обновился — Unity скачивает новые bundle’ы прозрачно.
Это особенно ценно для:
- DLC и сезонный контент — не пересобираете весь билд, кладёте новые ассеты на CDN.
- Hot fixes — починили ассет, не нужно ждать review в App Store.
- A/B-тесты контента — даёте разным игрокам разные группы ассетов.
Когда Resources всё-таки оправдан
- Один-два маленьких ассета, нужных всегда — например,
Resources/DefaultMaterial.mat. - Прототипы — пока проще, чем настраивать Addressables.
В продакшне 99% ассетов — через Addressables, оставшиеся — встроенные в сцены или Direct References.
Профайлинг и анализ
В Window → Asset Management → Addressables → Analyze есть набор правил, которые проверят:
- Все ли ссылки на ассеты резолвятся?
- Не дублируются ли одни ассеты в разных bundle’ах?
- Нет ли неиспользуемых ассетов в группах?
Также: Addressables Profiler показывает в рантайме, какие группы загружены, сколько занимают памяти, у кого reference counter что.
В следующей и последней главе главного раздела — HLSL-шейдеры подробнее.