Version: 2019.4
Construyendo AssetBundles
Using AssetBundles Natively

Dependencias AssetBundle

Los AssetBundles pueden volverse dependientes de otros AssetBundles si uno o más de los UnityEngine.Objects contiene una referencia a unUnityEngine.Object ubicado en otro bundle. No se produce una dependencia si el UnityEngine.Object contiene una referencia a unUnityEngine.Object que no está contenido en ningún AssetBundle. En este caso, una copia del objeto del que dependería el bundle se copiará en el bundle cuando usted construya los AssetBundles. Si varios objetos en múltiples bundles contienen una referencia al mismo objeto que no está asignado a un bundle, cada paquete que tendría una dependencia en ese objeto hará su propia copia del objeto y lo empaquetará en el AssetBundle construido.

Si un AssetBundle contiene una dependencia, es importante que los bundles que contienen esas dependencias se carguen antes de que se cargue el objeto que está intentando crear una instancia. Unity no intentará cargar dependencias automáticamente.

Considerando el siguiente ejemplo, un Material en unas referencias Bundle 1 a una Textura en una Bundle 2:

En este ejemplo, antes de cargar el material desde Bundle 1, necesitaría cargar Bundle 2 en la memoria. No importa qué orden cargue Bundle 1 y Bundle 2, lo importante es que Bundle 2 se carga antes de cargar el material desde Bundle 1. En la siguiente sección, analizaremos cómo puede utilizar los objetos AssetBundleManifest que hemos mencionado en la sección anterior para determinar y cargar dependencias en el tiempo de ejecución.

Duplicated information across AssetBundles

By default, Unity doesn’t optimize duplicated information across AssetBundles. This means multiple AssetBundles in your Project might contain the same information, such as a Material which is used by multiple Prefabs. Assets which are used in multiple AssetBundles are known as common Assets. These can affect memory resources and loading times.

This page describes how Unity manages duplicated information across AssetBundles, and how you can apply optimization.

Editor setup

By default, Unity doesn’t perform any optimization to reduce or minimize the memory required to store duplicate information. During build creation, Unity builds duplicates of any implicitly referenced Assets inside the AssetBundles. To prevent this duplication, assign common Assets (such as Materials) to their own AssetBundle.

For example: you could have an application with two Prefabs, both of which are assigned to their own AssetBundle. Both Prefabs share the same Material, which is not assigned to an AssetBundle. This Material references a Texture, which is not assigned to an AssetBundle.

If you follow the AssetBundle Workflow and use the example class CreateAssetBundles to build AssetBundles, each generated AssetBundle contains the Material (including its Shader and referenced Textures). In the example image below, the Prefab files have a size of 383 KB and 377 KB respectively.

If the project contains a larger number of Prefabs, this behaviour impacts the final installer size, and the runtime memory footprint when both AssetBundles are loaded. Data duplication across AssetBundles also impacts batching, because Unity considers each copy of the same Material as a unique Material.

To avoid data duplication, assign the Material and its referenced Assets to its own modulesmaterials AssetBundle. You can also tag the Material only, because the Texture dependency is also included in the AssetBundle automatically during the build process.

Now if you rebuild the AssetBundles, the generated output includes a separate modulesmaterials AssetBundle (359 KB), which contains the Material and its associated Texture. This significantly reduces the size of the other AssetBundles for the Prefabs (from roughly 380 KB in the previous iteration down to roughly 20 KB).

The image below illustrates this.

Runtime loading

When you extract common Assets to a single AssetBundle, be careful about dependencies. In particular, if you only use a Prefab to instantiate a module, the Materials do not load.

A Prefab without a loaded Material
A Prefab without a loaded Material

To solve this problem, load the Materials AssetBundle in memory before you load the AssetBundle that belongs to the module. In the following example, this happens in the variable 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<GameObject>("example-prefab");
        Instantiate(prefab);
    }
}

A Prefab with a correctly loaded Material
A Prefab with a correctly loaded Material

Note: When you use LZ4 compressed and uncompressed AssetBundles, AssetBundle.LoadFromFile only loads the catalog of its content in memory, but not the content itself. To check if this is happening, use the Memory Profiler package to inspect memory usage.

Construyendo AssetBundles
Using AssetBundles Natively