Unity 加载AssetBundle(加载对应的依赖)

要加载一个资源A,必须先去加载它的所有依赖资源。
要知道这个资源A依赖了哪些资源,必须先去加载AssetBundleManifest
通过AssetBundleManifest对象的GetAllDependencies(A)方法,获取它依赖的所有资源。
依赖资源都加载了,就可以去真正加载资源A了。
注意点:
1.资源A加载完了后,要记得Unload(false),资源A的依赖资源要在 资源A加载完成后,才能Unload(false),否则无法正常加载资源A。
2.不Unload的话也可以,那就自己做一个字典记录所有加载过的AssetBundle,还有它们的引用计数器。那样就可以先判断是否存在,然后再确定是否要去加载。
例子

using Unity Engine;
using System.Collections;
using System.Collections.Generic;
using System;

public class AssetBundleLoaderMgr: Singleton {

    public string m_assetPath = Application.streamingAssetsPath;
    string assetTail = ".unity3d";

    /// 加载目标资源
    public void LoadAssetBundle(string name, Action callback) {
        name = name + assetTail; //eg:ui/panel.unity3d
        Action action = (depenceAssetBundles) => {
            string realName = this.GetRuntimePlatform() + "/" + name; //eg:Windows/ui/panel.unity3d
            LoadResReturnWWW(realName, (www) => {
                int index = realName.LastIndexOf("/");
                string assetName = realName.Substring(index + 1);
                assetName = assetName.Replace(assetTail, "");
                AssetBundle assetBundle = www.assetBundle;
                UnityEngine.Object obj = assetBundle.LoadAsset(assetName); //LoadAsset(name),这个name没有后缀,eg:panel
                //卸载资源内存
                assetBundle.Unload(false);
                for (int i = 0; i < depenceAssetBundles.Count; i++) {
                    depenceAssetBundles.Unload(false);
                }
                //加载目标资源完成的回调
                callback(obj);
            });
        };
        LoadDependenceAssets(name, action);
    }
    

    /// 加载目标资源的依赖资源
    private void LoadDependenceAssets(string targetAssetName, Action > action) {
        Debug.Log("要加载的目标资源:" + targetAssetName); //ui/panel.unity3d
        Action dependenceAction = (manifest) => {
            List depenceAssetBundles = new List(); //用来存放加载出来的依赖资源的AssetBundle
            string[] dependences = manifest.GetAllDependencies(targetAssetName);
            Debug.Log("依赖文件个数:" + dependences.Length);
            int length = dependences.Length;
            int finishedCount = 0;
            if (length == 0) {
                //没有依赖
                action(depenceAssetBundles);
            } else {
                //有依赖,加载所有依赖资源
                for (int i = 0; i < length; i++) {
                    string dependenceAssetName = dependences;
                    dependenceAssetName = GetRuntimePlatform() + "/" + dependenceAssetName; //eg:Windows/altas/heroiconatlas.unity3d
                    //加载,加到assetpool
                    LoadResReturnWWW(dependenceAssetName, (www) => {
                        int index = dependenceAssetName.LastIndexOf("/");
                        string assetName = dependenceAssetName.Substring(index + 1);
                        assetName = assetName.Replace(assetTail, "");
                        AssetBundle assetBundle = www.assetBundle;
                        UnityEngine.Object obj = assetBundle.LoadAsset(assetName);
                        //assetBundle.Unload(false);
                        depenceAssetBundles.Add(assetBundle);
                        finishedCount++;
                        if (finishedCount == length) {
                            //依赖都加载完了
                            action(depenceAssetBundles);
                        }
                    });
                }
            }
        };
        LoadAssetBundleManifest(dependenceAction);
    }
    
    /// 加载AssetBundleManifest
    private void LoadAssetBundleManifest(Action action) {
        string manifestName = this.GetRuntimePlatform();
        manifestName = manifestName + "/" + manifestName; //eg:Windows/Windows
        LoadResReturnWWW(manifestName, (www) => {
            AssetBundle assetBundle = www.assetBundle;
            UnityEngine.Object obj = assetBundle.LoadAsset("AssetBundleManifest");
            assetBundle.Unload(false);
            AssetBundleManifest manif = obj as AssetBundleManifest;
            action(manif);
        });
    }
    

    public void LoadResReturnWWW(string name, Action callback) {
        string path = "file://" + this.m_assetPath + "/" + name;
        Debug.Log("加载:" + path);
        StartCoroutine(LoaderRes(path, callback));
    }
    
    IEnumerator LoaderRes(string path, Action callback) {
        WWW www = new WWW(path);
        yield
        return www;
        if (www.isDone) {
            callback(www);
        }
    }

    /// 平台对应文件夹
    private string GetRuntimePlatform() {
        string platform = "";
        if (Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsEditor) {
            platform = "Windows";
        } else if (Application.platform == RuntimePlatform.Android) {
            platform = "Android";
        } else if (Application.platform == RuntimePlatform.IPhonePlayer) {
            platform = "IOS";
        } else if (Application.platform == RuntimePlatform.OSXPlayer || Application.platform == RuntimePlatform.OSXEditor) {
            platform = "OSX";
        }
        return platform;
    }
}

测试

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

public class TestAssetBundleLoader: MonoBehaviour {
    
    Dictionary GameObjectPool = new Dictionary();
    
    void Start() {
        //要加载的资源的队列
        Queue needLoadQueue = new Queue();
        needLoadQueue.Enqueue("ui/plane");
        needLoadQueue.Enqueue("ui/cube");
        needLoadQueue.Enqueue("ui/sphere");
        Load(needLoadQueue);
    }
    
    void Load(Queue needLoadQueue) {
        if (needLoadQueue.Count > 0) {
            string needLoadAssetName = needLoadQueue.Dequeue();
            AssetBundleLoaderMgr.Instance.LoadAssetBundle(needLoadAssetName, (obj) => {
                GameObject go = GameObject.Instantiate(obj) as GameObject;
                int index = needLoadAssetName.LastIndexOf("/");
                string assetName = needLoadAssetName.Substring(index + 1);
                //加载出来的GameObject放到GameObjectPool存储
                GameObjectPool.Add(assetName, go);
                Load(needLoadQueue);
            });
        } else {
            Debug.Log("all finished");
        }
    }
}

你可能感兴趣的:(Unity3D)