Польза Addressables в Unity3D и варианты использования
В Unity3D есть новый инструмент Addressables, для чего он нужен и в чём сложности его использования читайте в этой статье.
Addressables следует использовать в тех случаях когда нужно:
-разделить сборку проекта и сборку ассетов для этого проекта, например, когда проект вырос до таких размеров, что сборка всего разом занимает часы, а баг в коде хочется починить быстро, и отловить можно только в билде, тогда ресурсы можно собрать единожды, исполняемая же часть будет собираться гораздо быстрее
-загрузить игровые ресурсы через сеть, при таком подходе можно распространять легковесный исполнительный файл, а все тяжёлые графические и аудио ресурсы загрузятся с сервера
-уменьшить потребление памяти, при обычном подходе, все префабы и связанные с ними ресурсы загружены в память уже в тот момент, когда сцена загружена, Addressables позволяет загружать и выгружать из памяти всё нужное в тот момент, когда в префабе пропала необходимость
-ускорить загрузку уровня, при старте уровня можно показать пользователю низкополигональные модели с текстурами низкого разрешения, а более качественные модели и текстуры загружать уже в тот момент, когда пользователь способен взаимодействовать со сценой, и не заставлять ждать когда всё загрузится полностью
Бонус: Addressables можно использовать, чтобы оценить сколько места занимают ресурсы относящиеся к определённой сцене.
Установка Addressables
Addressables устанавливается в проект при помощи Package Manager. Тремя простыми шагами:
Затем надо открыть окно с группами:
И создать файл настроек:
По умолчанию будет одна группа:
Каждая группа будет упаковывать принадлежащие ей ресурсы в отдельный файл. Создать новую можно вот так:
Как контент сделать загружаемым через Addressables.
Можно двумя способами сделать контент:
1) перетянув нужный файл в группу
2) поставив галочку в инспекторе рядом с надписью Addressable
Во втором варианте контент добавится в группу, которая стоит по умолчанию, сменить её можно нажав правой кнопкой мыши по группе и выбрав Set as Default.
Как использовать контент добавленный в Addressables
Пример кода для загрузки Sprite в Image:
Или можно иначе, используя async/await:
Имейте в виду, что два этих подхода могут отличаться результатом, если исполняемый компонент будет отключён до того как ресурс будет загружен.
Подход через IEnumerable в таком случае не даст нужного результата и картинка не будет показана, так как любая Coroutine на выключенном объекте прервётся.
Подход через async загрузит картинку в любом случае.
Пример кода для Prefab'а:
Или сокращённый вариант на случай, если нужно только отобразить объект в сцене:
Пример выше показывает насколько просто можно заменить обычный подход с инстанциированием префаба на инстанциирование Addressable-префаба. И можно пойти дальше. Если создать префаб, а потом перетянуть его из окна Project в поле скрипта, то этот префаб автоматически станет Addressable.
Пример кода для сцены:
При таком подходе надо файл сцены сделать Addressable, и установить ссылку в инспекторе. Учтите, что все необходимые для сцены ресурсы будут упакованы в файл той группы, в которую он добавлен, а если разные сцены, использующие общие объекты, будут в разных группах, то ресурсы продублируются в файлах этих групп. Поэтому делите контент с умом, либо общий контент выделите в отдельную группу и сделайте его Addressables.
И НЕ добавляйте сцены, загружаемые через Addressables, в список "Scenes In Build", иначе эти сцены будут занимать место и в самом билде и в файлах Addressables.
Как собрать исполняемый билд
Если мы соберём билд привычным способом, то получим ошибку:
Потому, что мы не поместили файлы Addressables рядом с исполняемым файлом. Возникает два вопроса:
1) Где взять файлы?
2) Куда и как их положить?
У каждой группы есть настройки откуда её загружать:
Build Path - куда скрипт сборки положит файлы
Load Path - откуда эти файлы будет пытаться загрузить процесс
Самый простой вариант - BuildTarget как на скриншоте.
После этого можно запускать сборку контента. Файлы будут лежать вот в этой папке:
Её же и нужно положить в корень папки билда рядом с exe.
Как загрузить контент через сеть
Для того чтобы файлы с контентом подгружались через сеть, в Addressables есть специальная опция, её можно задействовать открыв Profiles:
Задав ссылку на сервер:
И установив LoadPath равным RemoteLoadPath:
Как сэкономить память
Эта часть будет самой сложной в понимании, потому, что придётся понять и простить разработчиков этой новой системы. В презентациях обещают, что Addressables будет позволять выгружать из памяти всё ненужное и неиспользуемое в данный момент, но на самом деле это происходит не всегда, для версии 1.16.15 проблема актуальна.
Предположим, что всё работает как надо, тогда вот код, который позволит загрузить префаб, инстанциировать его и выгрузить через 5 секунд:
Важный момент - не удаляйте объекты через Destroy, или после обычного Destroy вызывайте Addressables.ReleaseInstance на объекте AsyncOperationHandle, тогда счётчик ссылок, который помогает Addressables выгружать ненужное, будет правильно понимать сколько ссылок осталось и вовремя выгрузит лишнее из памяти.
Так же инстанциируйте через Addressables.InstantiateAsync, это тоже связано со счётчиком. Загрузка через LoadAsync с последующим инстанциированием "как обычно" приведёт к тому, что Addressables не будет знать что выгружать надо, а что нельзя.
Для того, чтобы выгрузить из памяти сцену загруженную через Addressables надо всего лишь загрузить другую сцену в режиме Single.