Version: 5.3 (switch to 5.4b)
Загрузка и выгрузка объектов из AssetBundle
Сохранение и загрузка бинарных данных в AssetBundle

Отслеживание загружаемых пакетов ассетов (AssetBundles)

Unity позволит одновременно загружать в ваше приложение только один экземпляр пакета ассетов (AssetBundle). Это означает только то, что вы не сможете восстановить пакет ассетов (AssetBundle) из WWW объекта, если ранее был загружен точно такой же пакет, но при этом не был выгружен. На практике это означает что, когда вы пытаетесь получить доступ к ранее загруженному пакету ассетов (AssetBundle) следующим образом:

 AssetBundle bundle = www.assetBundle;



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

Please note that before Unity 5 all bundles would finish loading before any of the bundles would be unloaded. So calling AssetBundle.Unload function while some of the bundles are still being loaded will block the execution of the rest of the code until all bundles are loaded. This will add a performance hiccup. This has been reworked in Unity 5.

Если вам нужно отследить то, какие пакеты ассетов были вами загружены, тогда вы можете воспользоваться wrapper классом, который поможет вам управлять своими загрузками следующим образом:

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);
       }
   }
}

Пример использования класса будет следующим:

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);
   }
}

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

будет выдана следующая ошибка и свойство assetBundle возвратит значение null. Так как вы не можете восстановить пакет ассетов во время второй загрузки, если первая уже была завершена, тогда всё что вам нужно будет сделать, это также выгрузить неиспользуемый пакет ассетов или сохранить на него ссылку и избегать его загрузки, в случае если он уже загружен в память. Вы можете выбрать правильный план действий, основанный на ваших потребностях, но всё же мы рекомендуем вам выгрузить пакет ассетов сразу после того, как объекты из него будут загружены. Таким образом вы освободите память и избавитесь от сообщений, в которых будет говориться о загрузке кешированных пакетов ассетов (AssetBundles).

Загрузка и выгрузка объектов из AssetBundle
Сохранение и загрузка бинарных данных в AssetBundle