Мои Уведомления
Привет, !
Мой Аккаунт Мои Финансы Мои Подписки Мои Настройки Выход
Руководство API скрипты

Нативное использование AssetBundles

Существует четыре разных API, которые можно использовать для загрузки AssetBundles. Их поведение зависит от платформы, на которую загружается пакет, и сжатияметода хранения данных, который уменьшает объем памяти. это требует. См. Сжатие текстур, Сжатие анимации, Сжатие звука, Сжатие компоновки.
См. в Словарь
, использованном при сборке пакетов AssetBundles (несжатые, LZMA, LZ4 ).

Четыре API, с которыми нам предстоит работать:

AssetBundle.LoadFromMemoryAsync

AssetBundle.LoadFromMemoryAsync

Эта функция принимает массив байтов, содержащий данные AssetBundle. При желании вы также можете передать значение CRC, если хотите. Если пакет сжат LZMA, он распаковывает AssetBundle во время загрузки. Сжатые пакеты LZ4 загружаются в сжатом состоянии.

Here’s one example of how to use this method:

using UnityEngine; using System.Collections; using System.IO; public class Example : MonoBehaviour { IEnumerator LoadFromMemoryAsync(string path) { AssetBundleCreateRequest createRequest = AssetBundle.LoadFromMemoryAsync(File.ReadAllBytes(path)); yield return createRequest; AssetBundle bundle = createRequest.assetBundle; var prefab = bundle.LoadAsset("MyObject"); Instantiate(prefab); } }

Однако это не единственная стратегия, позволяющая использовать LoadFromMemoryAsync. File.ReadAllBytes(path) можно заменить любой желаемой процедурой получения байтового массива.

AssetBundle.LoadFromFile

AssetBundle.LoadFromFile

Этот API очень эффективен при загрузке несжатых пакетов из локального хранилища. LoadFromFile загрузит пакет непосредственно с диска, если пакет несжатый или сжатый фрагмент (LZ4). Загрузка полностью сжатого (LZMA) пакета с помощью этого метода сначала распаковывает пакет перед его загрузкой в память.

Один пример использования LoadFromFile:

using System.IO; using UnityEngine; public class LoadFromFileExample : MonoBehaviour { void Start() { var myLoadedAssetBundle = AssetBundle.LoadFromFile(Path.Combine(Application.streamingAssetsPath, "myassetBundle")); if (myLoadedAssetBundle == null) { Debug.Log("Failed to load AssetBundle!"); return; } var prefab = myLoadedAssetBundle.LoadAsset("MyObject"); Instantiate(prefab); } }

Примечание. На устройствах Android с Unity 5.3 или более ранней версии этот API не будет работать при попытке загрузить AssetBundles из пути потоковых ресурсов. Это связано с тем, что содержимое этого пути будет находиться внутри сжатого файла .jar. Unity 5.4 и более поздние версии могут прекрасно использовать этот вызов API с потоковыми активами.

UnityWebRequestAssetBundle

UnityWebRequestAssetBundle

UnityWebRequestAssetBundle имеет специальный вызов API для работы с AssetBundle. Для начала вам нужно создать веб-запрос с помощью UnityWebRequestAssetBundle.GetAssetBundle. После возврата запроса передайте объект запроса в DownloadHandlerAssetBundle.GetContent(UnityWebRequestAssetBundle). Этот вызов GetContent вернет ваш объект AssetBundle.

Вы также можете использовать свойство assetBundle в классе DownloadHandlerAssetBundle после загрузки пакета в загружать AssetBundle с эффективностью AssetBundle.LoadFromFile.

Вот пример того, как загрузить AssetBundle, который содержит два GameObjectфундаментальный объект в сценах Unity, который может представлять персонажей. , реквизит, декорации, камеры, путевые точки и многое другое. Функциональность GameObject определяется прикрепленными к нему компонентами. Подробнее
Просмотрите в Словарь
и создайте их. Чтобы начать этот процесс, нам просто нужно вызвать StartCoroutine(InstantiateObject());

IEnumerator InstantiateObject() { string uri = "file:///" + Application.dataPath + "/AssetBundles/" + assetBundleName; UnityEngine.Networking.UnityWebRequestAssetBundle request = UnityEngine.Networking.UnityWebRequestAssetBundle.GetAssetBundle(uri, 0); yield return request.SendWebRequest(); AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(request); GameObject cube = bundle.LoadAsset("Cube"); GameObject sprite = bundle.LoadAsset("Sprite"); Instantiate(cube); Instantiate(sprite); }

Загрузка ресурсов из AssetBundles

Теперь, когда вы успешно загрузили свой AssetBundle, пришло время, наконец, загрузить некоторые активы.

Общий фрагмент кода:

T objectFromBundle = bundleObject.LoadAsset(имя_актива);

T — это тип объекта, который вы пытаетесь загрузить.

Есть несколько вариантов загрузки ресурсов. У нас есть LoadAsset, LoadAllAssets и их асинхронные аналоги LoadAssetAsync и LoadAllAssetsAsync соответственно.

Вот как синхронно загрузить ресурс из AssetBundles:

Чтобы загрузить один игровой объект:

GameObject gameObject =loadAssetBundle.LoadAsset(assetName);

Чтобы загрузить все активы:

Unity.Object[] objectArray = loadedAssetBundle.LoadAllAssets();

Теперь, когда показанные ранее методы возвращают либо тип загружаемого объекта, либо массив объектов, асинхронные методы возвращают AssetBundleRequest. . Вам нужно будет дождаться завершения этой операции, прежде чем получить доступ к активу. Чтобы загрузить объект:

AssetBundleRequest request = loadedAssetBundleObject.LoadAssetAsync(assetName); yield return request; var loadedAsset = request.asset;

И

AssetBundleRequest request = loadedAssetBundle.LoadAllAssetsAsync(); yield return request; var loadedAssets = request.allAssets;

После того как вы загрузили свои активы, все готово! Вы можете использовать загруженные объекты так же, как любой другой объект в Unity.

Загрузка манифеста AssetBundle

Загрузка манифестов AssetBundle может быть невероятно полезной. Особенно при работе с зависимостями
AssetBundle. См. в Словарь
.

Чтобы получить пригодный для использования объект AssetBundleManifest, вам потребуется загрузить этот дополнительный пакет AssetBundle (тот, имя которого совпадает с именем папки, в которой он находится) и загрузить из него объект типа AssetBundleManifest.

Загрузка самого манифеста выполняется точно так же, как и любого другого актива из AssetBundle:

AssetBundle assetBundle = AssetBundle.LoadFromFile(manifestFilePath); AssetBundleManifest manifest = assetBundle.LoadAsset("AssetBundleManifest");

Теперь у вас есть доступ к вызовам API AssetBundleManifest через объект манифеста из приведенного выше примера. Отсюда вы можете использовать манифест для получения информации о созданных вами AssetBundles. Эта информация включает данные о зависимостях, хеш-данные и данные о вариантах для AssetBundles.

Помните, как в предыдущем разделе мы обсуждали зависимости AssetBundle и как, если пакет имел зависимость от другого пакета, эти пакеты нужно было бы загрузить перед загрузкой каких-либо ресурсов из исходного пакета? Объект манифеста делает возможным динамический поиск зависимостей загрузки. Допустим, мы хотим загрузить все зависимости для AssetBundle с именем «assetBundle».

AssetBundle assetBundle = AssetBundle.LoadFromFile(manifestFilePath); AssetBundleManifest manifest = assetBundle.LoadAsset("AssetBundleManifest"); string[] dependencies = manifest.GetAllDependencies("assetBundle"); //Pass the name of the bundle you want the dependencies for. foreach(string dependency in dependencies) { AssetBundle.LoadFromFile(Path.Combine(assetBundlePath, dependency)); }

Теперь, когда вы загружаете AssetBundles, зависимости AssetBundle и активы, пришло время поговорить об управлении всеми этими загруженными AssetBundle.

Управление загруженными пакетами ресурсов

Примечание. Адресные активы предоставляет готовую систему для управления загрузкой Asset Bundes, зависимостей и Assets. Unity рекомендует использовать Addressables, а не управлять AssetBundles самостоятельно.

См. также: Учебное пособие Unity Learn по управлению Загруженные AssetBundles

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

Важно знать, когда загружать и выгружать AssetBundle. Неправильная выгрузка AssetBundle может привести к дублированию объектов в памяти или другим нежелательным последствиям, например отсутствию текстур.

Самое важное, что нужно понять об управлении AssetBundle, — это когда вызывать AssetBundle.Unload(bool) или AssetBundle.UnloadAsync(bool) — и следует ли передавать true или false в вызов функции. Unload — это нестатическая функция, которая выгружает ваш AssetBundle. Этот API выгружает информацию заголовка вызываемого AssetBundle. Аргумент указывает, следует ли также выгружать все объекты, созданные из этого AssetBundle.

AssetBundle.Unload(true) выгружает все игровые объекты (и их зависимости), загруженные из AssetBundle. Сюда не входят скопированные игровые объекты (например, созданные экземпляры игровых объектов), поскольку они больше не принадлежат AssetBundle. Когда это происходит, текстуры, загруженные из этого AssetBundle (и все еще принадлежащие ему), исчезают из игровых объектов в сцене, и Unity рассматривает их как отсутствующие текстуры.

Предположим, что материал M загружается из AssetBundle AB, как показано ниже, и используется в Prefabтипе актива, который позволяет хранить GameObject с компонентами и свойствами. Префаб действует как шаблон, из которого вы можете создавать новые экземпляры объектов в сцене. Подробнее
См. в Словарь
стр.

Если вызывается AB.Unload(true). Любой экземпляр M в активной сцене также будет выгружен и уничтожен.

Если бы вы вместо этого вызвали AB.Unload(false), это разорвало бы цепочку текущих экземпляров M и AB.

Если AB снова загружается позже и вызывается AB.LoadAsset(), Unity не будет повторно связывать существующие копии M с вновь загруженным Материалом.

Если вы создадите еще один экземпляр Prefab P, он не будет использовать существующую копию M. Вместо этого будут загружены две копии M.

Как правило, использование AssetBundle.Unload(false) не приводит к идеальной ситуации. В большинстве проектов следует использовать AssetBundle.Unload(true) и принять метод, гарантирующий отсутствие дублирования объектов. Два распространенных метода:

  • Наличие четко определенных моментов в течение жизненного цикла приложения, в которые выгружаются временные пакеты AssetBundles, например между уровнями или во время экрана загрузки.

  • Ведение счетчиков ссылок для отдельных объектов и выгрузка AssetBundles только тогда, когда все составляющие их объекты не используются. Это позволяет приложению выгружать и перезагружать отдельные объекты без дублирования памяти.

Если приложение должно использовать AssetBundle.Unload(false), отдельные объекты можно выгрузить только двумя способами:

  • Удалите все ссылки на нежелательный объект как в сцене, так и в коде. После этого вызовите Resources.UnloadUnusedAssets.

  • Загружайте сцену неаддитивно. Это уничтожит все объекты в текущей сцене и автоматически вызовет Resources.UnloadUnusedAssets.

Вы можете отблагодарить автора, за перевод документации на русский язык. ₽ Спасибо
Руководство Unity 2021.3