Unity5.X AssetBundle加载

这里提供一个简单的ab加载管理器


using System.Collections;

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


public class LoadAssetBundleManager : MonoBehaviour {


    #region 声明变量


    #region 单例
    private static LoadAssetBundleManager instance;
    public static LoadAssetBundleManager Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new GameObject("LoadAssetBundleManager").AddComponent<LoadAssetBundleManager>();
            }
            return instance;
        }
    }
    #endregion


    #region 加载


    //AssetBundleManifest 总体的AssetBundleManifest
    AssetBundleManifest mainAssetBundleManifest;


    //下载路径
    string URL;
    //AssetBundleManifest 名字
    public string assetBundleManifestName = "";


    //下载完后的委托
    public delegate void HandleFinishDownload(WWW www);


    //加载完后的委托
    public delegate void HandleFinishInstantiate(Object go);


    #endregion


    #region 卸载


    Dictionary<string, LoadedAssetBundle> loadedAssetBundles;
    Dictionary<string, string[]> dependencies;


    #endregion


    #endregion


    #region 提供外部方法


    /// <summary>
    /// 加载所需要的AssetBundle
    /// </summary>
    /// <param name="assetBundleName"></param>
    /// <param name="instantiateFun"></param>
    /// <returns></returns>
    public IEnumerator LoadAssetBundle(string assetBundleName, HandleFinishInstantiate instantiateFun, bool isLoadScene = false)
    {
        AssetBundle assetBundle = null;


        assetBundle = LoadAssetBundleInternal(assetBundleName);


        if (assetBundle == null)
        {
            Debug.LogError("新加载____" + assetBundleName);
            //获取依赖文件列表
            string[] dependentAssetBundles = mainAssetBundleManifest.GetAllDependencies(assetBundleName);


            AddDependencies(assetBundleName, dependentAssetBundles);


            AssetBundle[] abs = new AssetBundle[dependentAssetBundles.Length];


            for (int i = 0; i < dependentAssetBundles.Length; i++)
            {
                //加载所有的依赖文件
                WWW www = new WWW(URL + dependentAssetBundles[i]);
                yield return www;
                abs[i] = www.assetBundle;


                AddLoadedAssetBundles(dependentAssetBundles[i], new LoadedAssetBundle(abs[i]));
            }


            //加载需要的文件
            WWW loadAssetBundle = new WWW(URL + assetBundleName);
            yield return loadAssetBundle;
            assetBundle = loadAssetBundle.assetBundle;


            AddLoadedAssetBundles(assetBundleName, new LoadedAssetBundle(assetBundle));


        }
        else
        {
            Debug.LogError("已经加载过了____" + assetBundleName);
        }


        if (isLoadScene)
        {
            //加载场景(使用场景名称)
            SceneManager.LoadScene(assetBundleName);
        }
        else
        {
            if (instantiateFun != null)
                instantiateFun(assetBundle.LoadAsset(assetBundleName));
        }


        //UnloadAssetBundle(assetBundleName);
    }


    /// <summary>
    /// 卸载目标AssetBundle
    /// </summary>
    /// <param name="assetBundleName"></param>
    /// <param name="unLoad"></param>
    public void UnloadAssetBundle(string assetBundleName, bool unLoad = false)
    {
        Debug.LogError("卸载____"+ assetBundleName);
        UnloadAssetBundleInternal(assetBundleName, unLoad);
        UnloadDependencies(assetBundleName, unLoad);
    }




    #endregion


    #region 内部方法实现


    void Awake()
    {
        instance = this;
        Initialize();
    }


    /// <summary>
    /// 初始化数据
    /// </summary>
    void Initialize()
    {
        //暂时只定义一种
        URL = "file://" + Application.streamingAssetsPath + "/";
        assetBundleManifestName = "StreamingAssets";
        LoadMainAssetBundleManifest();


        loadedAssetBundles = new Dictionary<string, LoadedAssetBundle>();
        dependencies = new Dictionary<string, string[]>();


    }


    /// <summary>
    /// 加载总体的AssetBundleManifest
    /// </summary>
    void LoadMainAssetBundleManifest()
    {
        StartCoroutine(DownLoad(URL + assetBundleManifestName, delegate (WWW www)
        {
            AssetBundle manifestBundle = www.assetBundle;
            mainAssetBundleManifest = (AssetBundleManifest)manifestBundle.LoadAsset("AssetBundleManifest");
            manifestBundle.Unload(false);
        }
        ));
    }


    /// <summary>
    /// 下载WWW
    /// </summary>
    /// <param name="url"></param>
    /// <param name="finishFun"></param>
    /// <returns></returns>
    private IEnumerator DownLoad(string url, HandleFinishDownload finishFun)
    {
        WWW www = new WWW(url);
        yield return www;
        if (www.error != null) Debug.LogError(www.error + "/" + url);
        if (finishFun != null)
            finishFun(www);
        www.Dispose();
    }


    /// <summary>
    /// dependencies 增
    /// </summary>
    /// <param name="mKey"></param>
    /// <param name="mValue"></param>
    private void AddDependencies(string mKey, string[] mValue)
    {
        dependencies.Add(mKey, mValue);
    }


    /// <summary>
    /// dependencies 删
    /// </summary>
    /// <param name="mKey"></param>
    private void UnloadDependencies(string mKey, bool unLoad = false)
    {
        string[] mDependencies = null;
        if (!dependencies.TryGetValue(mKey, out mDependencies)) return;


        foreach (var dependency in mDependencies)
        {
            UnloadAssetBundleInternal(dependency, unLoad);
        }


        dependencies.Remove(mKey);
    }


    /// <summary>
    /// loadedAssetBundles 增
    /// </summary>
    /// <param name="mKey"></param>
    /// <param name="mValue"></param>
    private void AddLoadedAssetBundles(string mKey, LoadedAssetBundle mValue)
    {
        loadedAssetBundles.Add(mKey, mValue);
    }


    /// <summary>
    /// 从内部加载AssetBundle
    /// </summary>
    /// <param name="assetBundleName"></param>
    /// <returns></returns>
    private AssetBundle LoadAssetBundleInternal(string assetBundleName)
    {
        LoadedAssetBundle bundle = null;
        loadedAssetBundles.TryGetValue(assetBundleName, out bundle);
        if (bundle != null)
        {
            bundle.referencedCount++;
            return bundle.assetBundle;
        }
        return null;
    }


    /// <summary>
    /// 从内部卸载AssetBundle
    /// </summary>
    /// <param name="assetBundleName"></param>
    private void UnloadAssetBundleInternal(string assetBundleName, bool unLoad = false)
    {
        LoadedAssetBundle bundle = GetLoadedAssetBundle(assetBundleName);
        if (bundle == null)
            return;


        if (--bundle.referencedCount == 0)
        {
            bundle.assetBundle.Unload(unLoad);
            loadedAssetBundles.Remove(assetBundleName);
        }
    }


    /// <summary>
    /// 获取加载过的AssetBundle
    /// </summary>
    /// <param name="assetBundleName"></param>
    /// <returns></returns>
    private LoadedAssetBundle GetLoadedAssetBundle(string assetBundleName)
    {
        LoadedAssetBundle bundle = null;
        loadedAssetBundles.TryGetValue(assetBundleName, out bundle);
        if (bundle == null)
            return null;


        string[] mDependencies = null;
        if (!dependencies.TryGetValue(assetBundleName, out mDependencies))
            return bundle;


        foreach (var dependency in mDependencies)
        {
            LoadedAssetBundle dependentBundle;
            loadedAssetBundles.TryGetValue(dependency, out dependentBundle);
            if (dependentBundle == null)
                return null;
        }


        return bundle;
    }




    #endregion


    #region 测试


    public string assetBundleName;
    public string changeMatName;


    void OnGUI()
    {
        if (GUILayout.Button("Load Cube"))
        {
            StartCoroutine(LoadAssetBundle(assetBundleName, delegate (Object go)
             {
                 GameObject obj = Instantiate(go) as GameObject;
                 obj.transform.position = new Vector3(Random.Range(0, 5), 0, Random.Range(0, 5));
             }));
        }


        if (GUILayout.Button("UnLoad Cube"))
        {
            UnloadAssetBundle(assetBundleName);
        }


        if (GUILayout.Button("UnLoad Cube True"))
        {
            UnloadAssetBundle(assetBundleName, true);
        }


        if (GUILayout.Button("ChangeMat"))
        {
            StartCoroutine(LoadAssetBundle(changeMatName, delegate (Object go)
            {
                GameObject obj = GameObject.Find("TestCube(Clone)");
                obj.GetComponent<MeshRenderer>().material = go as Material;
            }));
        }
    }


    #endregion




}


public class LoadedAssetBundle
{
    public AssetBundle assetBundle;
    public int referencedCount;


    public LoadedAssetBundle(AssetBundle ab)
    {
        assetBundle = ab;
        referencedCount = 1;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值