AssetBundles могут стать зависимыми от других AssetBundles, если один или несколько UnityEngine.Objects
содержат ссылку на UnityEngine.Object
находится в другой связке. зависимость
See in Словарь не возникает, если UnityEngine.Object
содержит ссылку на UnityEngine.Object
, который не содержится ни в одном AssetBundle. В этом случае копия объекта, от которого будет зависеть пакет, копируется в пакет при сборке AssetBundles. Если несколько объектов в нескольких пакетах содержат ссылку на один и тот же объект, который не назначен пакету, каждый пакет, который будет иметь зависимость от этого объекта, создаст собственную копию объекта и упакует его в созданный пакет AssetBundle. р>
Если AssetBundle содержит зависимость, важно, чтобы пакеты, содержащие эти зависимости, были загружены до загрузки объекта, экземпляр которого вы пытаетесь создать. Unity не будет пытаться автоматически загружать зависимости.
В следующем примере Материал в Наборе 1 ссылается на Текстуру в Наборе 2:
В этом примере перед загрузкой материала из Bundle 1 вам необходимо загрузить в память Bundle 2. Неважно, в каком порядке вы загружаете Набор 1 и Набор 2, главное, что Набор 2 загружается до загрузки Материала из < b>Набор 1. В следующем разделе мы обсудим, как можно использовать объекты AssetBundleManifest
, которые мы затронули в предыдущем разделе, для определения и загрузки зависимостей во время выполнения.
Дублирующаяся информация в AssetBundles
По умолчанию Unity не оптимизирует повторяющуюся информацию в AssetBundles. Это означает, что несколько AssetBundles в вашем Проекте могут содержать одну и ту же информацию, например, Материал, который используется несколькими PrefabТип ресурса, который позволяет хранить GameObject вместе с компонентами и свойствами. Префаб действует как шаблон, из которого вы можете создавать новые экземпляры объектов в сцене. Подробнее
См. в Словарь. Активы, которые используются в нескольких AssetBundle, называются общими активами. Это может повлиять на ресурсы памяти и время загрузки.
На этой странице описывается, как Unity управляет дублирующейся информацией в AssetBundles и как можно применить оптимизацию.
Настройка редактора
По умолчанию Unity не выполняет никакой оптимизации для уменьшения или минимизации объема памяти, необходимого для хранения повторяющейся информации. Во время создания сборки Unity создает дубликаты любых активов, на которые неявно ссылаются внутри AssetBundles. Чтобы предотвратить это дублирование, назначьте общие активы (например, материалы) их собственному AssetBundle.
Например: у вас может быть приложение с двумя префабами, каждый из которых назначен своему собственному AssetBundle. Оба префаба используют один и тот же материал, который не назначен AssetBundle. Этот материал ссылается на текстуру, которая не назначена AssetBundle.
Если вы следуете рабочему процессу AssetBundle и используете пример класса CreateAssetBundles
для создания AssetBundles, каждый сгенерированный AssetBundle содержит Материал (включая его шейдер и упомянутые текстуры). На приведенном ниже примере файлы Prefab имеют размер 383 КБ и 377 КБ соответственно.
Если проект содержит большое количество префабов, это повлияет на окончательный размер установщика и объем памяти во время выполнения при загрузке обоих пакетов AssetBundle. Дублирование данных в AssetBundles также влияет на пакетную обработку, поскольку Unity рассматривает каждую копию одного и того же Материала как уникальный Материал.
Чтобы избежать дублирования данных, назначьте Материал и связанные с ним Активы собственному modulesmaterials
AssetBundle. Вы также можете пометить только материал, потому что зависимость текстуры также автоматически включается в AssetBundle во время процесса сборки.
Теперь, если вы перестроите AssetBundles, сгенерированные выходные данные будут включать отдельный AssetBundle modulesmaterials
(359 КБ), который содержит Материал и связанную с ним Текстуру. Это значительно уменьшает размер других пакетов AssetBundles для префабов (примерно с 380 КБ в предыдущей итерации до примерно 20 КБ).
Изображение ниже иллюстрирует это.
Загрузка во время выполнения
При извлечении общих активов в один пакет AssetBundle будьте осторожны с зависимостями. В частности, если вы используете префаб только для создания экземпляра модуля, материалы не загружаются.
Чтобы решить эту проблему, загрузите в память набор материалов AssetBundle перед загрузкой пакета AssetBundle, принадлежащего модулю. В следующем примере это происходит в переменной materialsAB
.
using System.IO;
using UnityEngine;
public class InstantiateAssetBundles : MonoBehaviour
{
void Start()
{
var materialsAB = AssetBundle.LoadFromFile(Path.Combine(Application.dataPath, Path.Combine("AssetBundles", "modulesmaterials")));
var moduleAB = AssetBundle.LoadFromFile(Path.Combine(Application.dataPath, Path.Combine("AssetBundles", "example-prefab")));
if (moduleAB == null)
{
Debug.Log("Failed to load AssetBundle!");
return;
}
var prefab = moduleAB.LoadAsset("example-prefab");
Instantiate(prefab);
}
}
Примечание. При использовании сжатых и несжатых пакетов AssetBundle LZ4 AssetBundle.LoadFromFile загружает только каталог своего содержимого. в памяти, но не в самом содержании. Чтобы проверить, происходит ли это, используйте Memory Profiler. пакет для проверки использования памяти.