Cargar y quitar objetos desde un AssetBundle
Almacenando y cargando datos binarios en un AssetBundle

Llevar un Seguimiento de los AssetBundles cargados

Unity solamente le va a permitir a usted tener una sola instancia de un AssetBundle en particular cargado a la vez en su aplicación. Lo que esto significa es que usted no puede recuperar un AssetBundle de un objeto WWW si el mismo ha sido cargado previamente y no ha descargado (unload) completamente. En términos prácticos significa que cuando usted intente acceder a un AssetBundle previamente cargado así:

 AssetBundle bundle = www.assetBundle;



 Cannot load cached AssetBundle. A file of the same name is already loaded from another AssetBundle

Por favor tenga en cuenta que antes de Unity 5 todos los bundles terminaban de cargar antes de que cualquiera de los bundles fueran descargados (unload). Entonces llamar la función AssetBundle.Unload mientras algunos de los bundles todavía están siendo cargados va a bloquear la ejecución del resto del códio hasta que todos los bundles sean cargados. Esto añadirá un hipo de rendimiento. Esto ha sido re-trabajado en Unity 5.

Si usted no quiere hacerle un seguimiento a qué AssetBundles ha descargado, usted puede utilizar una clase wrapper para ayudarlo a manejar sus descargas así:

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;

static public class AssetBundleManager {
   // A dictionary to hold the AssetBundle references
   static private Dictionary<string, AssetBundleRef> dictAssetBundleRefs;
   static AssetBundleManager (){
       dictAssetBundleRefs = new Dictionary<string, AssetBundleRef>();
   }
   // Class with the AssetBundle reference, url and version
   private class AssetBundleRef {
       public AssetBundle assetBundle = null;
       public int version;
       public string url;
       public AssetBundleRef(string strUrlIn, int intVersionIn) {
           url = strUrlIn;
           version = intVersionIn;
       }
   };
   // Get an AssetBundle
   public static AssetBundle getAssetBundle (string url, int version){
       string keyName = url + version.ToString();
       AssetBundleRef abRef;
       if (dictAssetBundleRefs.TryGetValue(keyName, out abRef))
           return abRef.assetBundle;
       else
           return null;
   }
   // Download an AssetBundle
   public static IEnumerator downloadAssetBundle (string url, int version){
       string keyName = url + version.ToString();
       if (dictAssetBundleRefs.ContainsKey(keyName))
           yield return null;
       else {
           while (!Caching.ready)
               yield return null;

           using(WWW www = WWW.LoadFromCacheOrDownload (url, version)){
               yield return www;
               if (www.error != null)
                   throw new Exception("WWW download:" + www.error);
               AssetBundleRef abRef = new AssetBundleRef (url, version);
               abRef.assetBundle = www.assetBundle;
               dictAssetBundleRefs.Add (keyName, abRef);
           }
       }
   }
   // Unload an AssetBundle
   public static void Unload (string url, int version, bool allObjects){
       string keyName = url + version.ToString();
       AssetBundleRef abRef;
       if (dictAssetBundleRefs.TryGetValue(keyName, out abRef)){
           abRef.assetBundle.Unload (allObjects);
           abRef.assetBundle = null;
           dictAssetBundleRefs.Remove(keyName);
       }
   }
}

Un ejemplo de uso de la clase sería:

using UnityEditor;

class ManagedAssetBundleExample : MonoBehaviour {
   public string url;
   public int version;
   AssetBundle bundle;
   void OnGUI (){
       if (GUILayout.Label ("Download bundle"){
           bundle = AssetBundleManager.getAssetBundle (url, version);
           if(!bundle)
               StartCoroutine (DownloadAB());
       }
   }
   IEnumerator DownloadAB (){
       yield return StartCoroutine(AssetBundleManager.downloadAssetBundle (url, version));
       bundle = AssetBundleManager.getAssetBundle (url, version);
   }
   void OnDisable (){
       AssetBundleManager.Unload (url, version);
   }
}

Por favor tenga en cuenta que la clase AssetBundleManager en este ejemplo es estática, y cualquier Assetbundles que usted está referenciando no serán destruidos cuando cargue una nueva escena. Utilice esta clase como una guía pero como se recomienda en el inicio es mejor si usted unload de los AssetBundles después de que han sido utilizados. Usted siempre puede clonar un objeto de una instancia previa, quitando la necesidad de cargar (load) los AssetBundles nuevamente.

el siguiente error sería lanzado y la propiedad de assetbundle devolvería null. Ya que usted no puede recuperar el AssetBundle durante la segunda descarga si la primera todavía está cargada (loaded), lo que usted necesita hacer es ya sea unload el AssetBundle cuando usted ya no lo esté utilizando, o mantener una refernecia a este y evitar que se descargue si todavía sigue en memoria. Usted puede decidir el curso correcto de acción basándose en sus necesidades, pero nuestra recomendación es que usted unload el AssetBundle tan pronto como usted haya finalizado de cargar (loading) los objetos. Esto va a liberar la memoria y usted ya no va a obtener un error acerca de cargar (load) AssetBundles en caché.

Cargar y quitar objetos desde un AssetBundle
Almacenando y cargando datos binarios en un AssetBundle