Estructura Interna de Asset Bundle
Cargar y quitar objetos desde un AssetBundle

Descargar AssetBundles

En esta sección se asume que conoces sobre cómo construir AssetBundles. Si no es así, favor ver la página Construcción de AssetBundles

Hay dos formas de descargar un AssetBundle:

  1. Non-caching: Esta se hace creando un nuevo objeto WWW. Los AssetBundles no están cacheados en la carpeta Cache de Unity en el dispositivo de almacenamiento local.
  2. Caching: Esto se hace usando el método WWW.LoadFromCacheOrDownload. Los AssetBundles son cacheados a la carpeta Cache de Unity en el dispositivo local de almacenamiento. El caché compartido del WebPlayer permite hasta 50 MB de AssetBundles cacheados. Las aplicaciones autónomas para PC/Mac y las aplicaciones iOS/Android tienen un límite de 4 GB. Las aplicaciones de WebPlayer que hacen uso de un caché dedicado están limitadas al número de bytes especificado en el acuerdo de licencia de caching. Para otras plataformas, favor remitirse a la documentación de scripting.

A continuación hay un ejemplo de descarga con non-caching:

using System;
using UnityEngine;
using System.Collections; class NonCachingLoadExample : MonoBehaviour {
   public string BundleURL;
   public string AssetName;
   IEnumerator Start() {
     // Download the file from the URL. It will not be saved in the Cache
     using (WWW www = new WWW(BundleURL)) {
         yield return www;
         if (www.error != null)
             throw new Exception("WWW download had an error:" + www.error);
         AssetBundle bundle = www.assetBundle;
         if (AssetName == "")
             Instantiate(bundle.mainAsset);
         else
             Instantiate(bundle.LoadAsset(AssetName));
                   // Unload the AssetBundles compressed contents to conserve memory
                   bundle.Unload(false);

     } // memory is freed from the web stream (www.Dispose() gets called implicitly)
   }
}

La manera recomendada para descargar AssetBundles es usando WWW.LoadFromCacheOrDownload. Por ejemplo:

using System;
using UnityEngine;
using System.Collections;

public class CachingLoadExample : MonoBehaviour {
    public string BundleURL;
    public string AssetName;
    public int version;

    void Start() {
        StartCoroutine (DownloadAndCache());
    }

    IEnumerator DownloadAndCache (){
        // Wait for the Caching system to be ready
        while (!Caching.ready)
            yield return null;

        // Load the AssetBundle file from Cache if it exists with the same version or download and store it in the cache
        using(WWW www = WWW.LoadFromCacheOrDownload (BundleURL, version)){
            yield return www;
            if (www.error != null)
                throw new Exception("WWW download had an error:" + www.error);
            AssetBundle bundle = www.assetBundle;
            if (AssetName == "")
                Instantiate(bundle.mainAsset);
            else
                Instantiate(bundle.LoadAsset(AssetName));
                    // Unload the AssetBundles compressed contents to conserve memory
                    bundle.Unload(false);

        } // memory is freed from the web stream (www.Dispose() gets called implicitly)
    }
}

Cuando accedes a la propiedad .assetBundle, los datos descargados son extraídos y el objeto AssetBundle es creado. A este punto, estás listo para cargar los objetos contenidos en el bundle. El segundo parámetro que se pasa a LoadFromCacheOrDownload especifica la versión del AssetBundle que será descargada. Si el AssetBundle no existe en el caché o si tiene una versión más baja que la solicitada, LoadFromCacheOrDownload descargará el AssetBundle. De lo contrario el AssetBundle será descargado desde el caché.

Favor notar que máximo una sola descarga del AssetBundle puede finalizarse por cada marco, cuando son descargados con WWW.LoadFromCacheOrDownload.

Poniendo todo junto

Ahora que los componentes están en su lugar, puedes construir una escena que podrás cargar tu AssetBundle y mostrar el contenido en la pantalla.

Final project structure
Final project structure

Primero crea un GameObject vacío con GameObject->CreateEmpty. Arrastra el script CachingLoadExample al GameObject vacío que acabaste de crear. Luego escribe el URL de tu AssetBundle en el campo BundleURL. Como se ha colocado en el directorio del proyecto, puedes copiar el path del archivo y luego se agrega el prefijo file://, por ejemplo file://C:/UnityProjects/AssetBundlesGuide/Assets/AssetBundles/Cube.unity3d.

Ahora puedes dar play en el Editoy, y deberías ver al prefab Cube siendo cargado desde el AssetBundle.

Cargar AssetBundles en el Editor

Al estar trabajando en el Editor con AssetBundles requeridos para ser construidos y cargados, esto puede volver lento el proceso de desarrollo. Por ejemplo: si un Asset de un AssetBundle es modificado, entonces esto requerirá que el AssetBundle sea reconstruido y en ambiente de producción es muy probable que todos los AssetBundles sean construidos juntos, por lo que realizar el proceso de actualizar un solo AssetBundle pueda volverse una operación de mucho tiempo. Un mejor enfoque es tener una ruta de código por separado en el Editor que cargará el Asset directamente en vez de cargarlo desde un AssetBundle. Para hacer esto, se puede usar Resources.LoadAssetAtPath (sólo en Editor).

// C# Example
// Loading an Asset from disk instead of loading from an AssetBundle
// when running in the Editor
using System.Collections;
using UnityEngine;

class LoadAssetFromAssetBundle : MonoBehaviour
{
    public Object Obj;

    public IEnumerator DownloadAssetBundle<T>(string asset, string url, int version) where T : Object {
        Obj = null;

#if UNITY_EDITOR
        Obj = Resources.LoadAssetAtPath("Assets/" + asset, typeof(T));
        yield return null;

#else
        // Wait for the Caching system to be ready
        while (!Caching.ready)
            yield return null;

        // Start the download
        using(WWW www = WWW.LoadFromCacheOrDownload (url, version)){
            yield return www;
            if (www.error != null)
                        throw new Exception("WWW download:" + www.error);
            AssetBundle assetBundle = www.assetBundle;
            Obj = assetBundle.LoadAsset(asset, typeof(T));
            // Unload the AssetBundles compressed contents to conserve memory
            bundle.Unload(false);

        } // memory is freed from the web stream (www.Dispose() gets called implicitly)

#endif
    }
}

Estructura Interna de Asset Bundle
Cargar y quitar objetos desde un AssetBundle