Unity 一次只允许加载一个特定资源包 (AssetBundle) 实例到应用程序中。这意味着您无法检索 WWW 对象中之前已加载的相同资源包 (AssetBundle) 或尚未加载的资源包。实际上,这意味着您尝试访问之前已下载的如下资源包 (AssetBundle) 时:
AssetBundle bundle = www.assetBundle;
程序将引出以下错误
Cannot load cached AssetBundle.A file of the same name is already loaded from another AssetBundle
且资源包属性将返回 null。如果第一次下载时下载了该资源包 (AssetBundle),则第二次下载时无法检索到该资源包,因此,无需再使用该资源包时,可以将其卸载 或获取其引用,并在它存在于内存中时避免将其下载。可根据需求决定需要采取的相应措施,但我们建议在加载完对象后立即卸载该资源包 (AssetBundle)。这可释放内存空间,并且不会再收到有关加载已缓存资源包 (AssetBundles) 的错误。
如需跟踪已下载资源包 (AssetBundles),可使用 包装类协助管理下载,如下: - <pre class="">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 {
- 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);
- }
- }
- }</pre><p style="margin-bottom: 15px;">An example usage of the class would be:</p><pre>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);
- }
- }</pre>
复制代码请记住,本示例中的 AssetBundleManager 类是静态的,正在引用的任何资源包 (AssetBundles) 不会在加载新场景时销毁。请将此类当做指南例程,但正如最初建议的那样,最好在使用后立即卸载资源包 (AssetBundles)。您始终可以克隆之前实例化的对象,无需再下载该资源包 (AssetBundles)。
|