Unity5 AssetBundle管理

来源:互联网 发布:苹果mac商店 编辑:程序博客网 时间:2024/06/05 05:52
//********************************************************************// 文件名: ABMgr.cs// 描述: AssetBundle管理// 作者: 李伟// 创建时间: 2015-07-16////********************************************************************using SK;using UnityEngine;using UnityEngine.Events;using System.Collections;using System.Collections.Generic;public class ABMgr : Singleton<ABMgr>{    public void Init()    {        D.Log("ABMgr Init()");        _downloadFaildNeedRemoveList = new List<string>();        _downloadSuccessdNeedRemoveList = new List<string>();        _assetBundleDic = new Dictionary<string, LoadedAssetBundle>();        _downloadingWWWDic = new Dictionary<string, WWWLoad>();        _downloadingEventDic = new Dictionary<string, DownloadingSameObjEvent>();    }    public void Reset()    {        FreeAllAssets();        Init();    }/*==================================================================================*/    private Dictionary<string, DownloadingSameObjEvent> _downloadingEventDic;    private Dictionary<string, LoadedAssetBundle> _assetBundleDic;    private Dictionary<string, WWWLoad> _downloadingWWWDic;    private List<string> _downloadFaildNeedRemoveList;    private List<string> _downloadSuccessdNeedRemoveList;    public struct WWWLoad    {        private string _abName;        private WWW _www;        private bool _canUseCache;        public WWW WWW        {            get             {                return _www;            }        }        public string ABName        {            get            {                return _abName;            }        }        public AssetBundle AssetBundle        {            get            {                if(WWW.isDone)                {                    return WWW.assetBundle;                }                else                {                    D.Log("[WWWLoad] [AssetBundle] WWW is null");                    return null;                }            }        }        public void SetData(            bool canUseCache,             string url,             string abName,            int version)        {            init();            _canUseCache = canUseCache;            _abName = abName;            _www = getWWW(url, version);        }        private WWW getWWW(string url, int version)        {            if (_canUseCache)            {                return WWW.LoadFromCacheOrDownload(url, version);            }            else            {                return new WWW(url);            }        }        private void init()        {            _www = null;            _canUseCache = false;        }        public float GetProgress()        {            return _www == null ? 0f : _www.progress;        }    }    public void DownloadManifest(string abName, UnityAction<string> callback)    {        var url = string.Format("{0}{1}{2}", PathMgr.Self.ABDownloadPath, abName, "");        var version = Global.Self.AssetBundleVersion;        WWWLoad load = new WWWLoad();        load.SetData(false, url, abName,version);        request(load, abName, callback);    }    public void Download(string abName, UnityAction<string> callback)    {        var url = string.Format("{0}{1}{2}", PathMgr.Self.ABDownloadPath, abName, "");        var version = Global.Self.AssetBundleVersion;        WWWLoad load = new WWWLoad();        load.SetData(false, url, abName, version);        request(load, abName, callback);    }    public void Download(string[] abNameArr, UnityAction<bool> callback)    {        List<string> abNameList = new List<string>();        foreach(var item in abNameArr)        {            abNameList.Add(item);        }        Download(abNameList, callback);    }    public void Download(List<string> abNameList, UnityAction<bool> callback)    {        var successList = new List<string>();        //定义一个action用来回调        UnityAction<string> action = (abNameTemp) =>         {            if (_assetBundleDic.ContainsKey(abNameTemp) && !successList.Contains(abNameTemp))            {                successList.Add(abNameTemp);                if (successList.Count == abNameList.Count && callback != null)                {                    callback(true);                }            }        };        foreach (var abName in abNameList)        {            //如果已经下载,直接加入下载成功,不需要再下载            if (_assetBundleDic.ContainsKey(abName) && !successList.Contains(abName))            {                action(abName);                continue;            }            var url = string.Format("{0}{1}{2}", PathMgr.Self.ABDownloadPath, abName, "");            var version = Global.Self.AssetBundleVersion;            WWWLoad load = new WWWLoad();            load.SetData(false, url, abName, version);            request(load, abName, action);        }    }    private void request(WWWLoad load, string abName, UnityAction<string> downloadingSameObjAction)    {        if(_assetBundleDic.ContainsKey(abName))        {            D.Log(abName + " has downloaded.");            return;        }        if (!_downloadingEventDic.ContainsKey(abName))        {            var evnet = new DownloadingSameObjEvent();            _downloadingEventDic.Add(abName, evnet);        }        _downloadingEventDic[abName].AddListener(downloadingSameObjAction);        if (_downloadingWWWDic.ContainsKey(abName))        {            D.Log(abName + " is downloading.");            return;        }        _downloadingWWWDic.Add(abName, load);    }    public bool IsContainItem(string item)    {        return _assetBundleDic.ContainsKey(item);    }    public AssetBundle GetItem(string item)    {        if (IsContainItem(item))        {             return _assetBundleDic[item].AssetBundle;        }        return null;    }    public Object GetItemChild(string item, string name)    {        return _assetBundleDic[item].AssetBundle.LoadAsset(name);    }    public void FreeAssets(string[] items)    {        foreach (var item in items)        {            FreeAsset(item);        }    }    public void FreeAssets(List<string> items)    {        FreeAssets(items.ToArray());    }    public void FreeAllAssets()    {        List<string> items = new List<string>();        foreach (KeyValuePair<string, LoadedAssetBundle> obj in _assetBundleDic)        {            items.Add(obj.Key);        }        foreach(var item in items)        {            FreeAsset(item);        }    }    public void FreeAsset(string item)    {        _assetBundleDic[item].AssetBundle.Unload(false);        _assetBundleDic.Remove(item);        D.Log("[Asset Bundle]Free asset : " + item);    }    public void Update()    {        _downloadFaildNeedRemoveList.Clear();        _downloadSuccessdNeedRemoveList.Clear();        foreach (var keyValue in _downloadingWWWDic)        {            WWWLoad wwwLoad = keyValue.Value;            if (wwwLoad.WWW.error != null)            {                D.Error(wwwLoad.WWW.error);                _downloadFaildNeedRemoveList.Add(keyValue.Key);                continue;            }            if (wwwLoad.WWW.isDone)            {                D.Log("[ABMgr][Downloaded] : " + keyValue.Key + " isDone");                var loadedAssetBundle = new LoadedAssetBundle(keyValue.Key, wwwLoad.AssetBundle);                if (!_assetBundleDic.ContainsKey(keyValue.Key))                {                    _assetBundleDic.Add(keyValue.Key, loadedAssetBundle);                }                _downloadSuccessdNeedRemoveList.Add(keyValue.Key);            }        }        DownloadSuccessFaild();        DownloadSuccess();    }    private void DownloadSuccessFaild()    {        foreach (var key in _downloadFaildNeedRemoveList)        {            WWWLoad wwwload = _downloadingWWWDic[key];            _downloadingWWWDic.Remove(key);            wwwload.WWW.Dispose();        }    }    private void DownloadSuccess()    {        foreach (var key in _downloadSuccessdNeedRemoveList)        {            WWWLoad wwwload = _downloadingWWWDic[key];            if (_downloadingEventDic.ContainsKey(key))            {                _downloadingEventDic[key].Invoke(key);                _downloadingEventDic[key].RemoveAllListeners();                _downloadingEventDic.Remove(key);            }            _downloadingWWWDic.Remove(key);            wwwload.WWW.Dispose();        }    }}public class LoadedAssetBundle{    public string _name;    public AssetBundle _assetBundle;    public int _referencedCount;    public string Name { get { return _name; } }    public AssetBundle AssetBundle { get { return _assetBundle; } }    public int ReferencedCount { get { return _referencedCount; } }    public LoadedAssetBundle(string name, AssetBundle assetBundle)    {        _name = name;        _assetBundle = assetBundle;        _referencedCount = 1;    }}
//********************************************************************// 文件名: Load.cs// 描述: Load加载策略的基类// 作者: 李伟// 创建时间: 2015-07-16////********************************************************************using SK;using UnityEngine;using UnityEngine.Events;using System.Collections;using System.Collections.Generic;public class Load{    private string _abName;    private UnityAction _loadAction;    private static AssetBundleManifest _assetBundlesManifest;    public static void LoadAssetBundlesManifest(UnityAction callback)    {        if (ABMgr.Self.IsContainItem("AssetBundles"))        {            if (callback != null)            {                callback();            }            return;        }        ABMgr.Self.DownloadManifest("AssetBundles", abName =>        {            if ("AssetBundles" == abName && ABMgr.Self.IsContainItem("AssetBundles"))            {                _assetBundlesManifest = ABMgr.Self.GetItemChild("AssetBundles", "AssetBundleManifest") as AssetBundleManifest;                if (callback != null) callback();            }            else            {                D.Error("[Load][LoadAssetBundlesManifest] ERROR");            }        });    }    public Load(string abName, UnityAction callback)    {        _abName = abName;        _loadAction = callback;    }    public void BeginLoad()    {        if (ABMgr.Self.IsContainItem(_abName))        {            _loadAction();            return;        }        if (_assetBundlesManifest != null)        {            string[] arr = _assetBundlesManifest.GetAllDependencies(_abName);            if (arr.Length == 0)            {                ABMgr.Self.Download(_abName, abName =>                 {                    if (abName == _abName) _loadAction();                });            }            else            {                var needDownLoadList = new List<string>();                foreach (var item in arr)                {                    if (!ABMgr.Self.IsContainItem(item)) needDownLoadList.Add(item);                }                ABMgr.Self.Download(needDownLoadList, isSuccess =>                {                    if (isSuccess)                    {                        ABMgr.Self.Download(_abName, abName =>                        {                            if (abName == _abName) _loadAction();                        });                    }                });            }        }    }}
//********************************************************************// 文件名: Singleton.cs// 描述: 通用类// 作者: 李伟// 创建时间: 2015-07-15////********************************************************************using System;using UnityEngine;using System.Collections;using System.Linq.Expressions;namespace SK{    public class Singleton<T>  where T : new()    {        private static T _self;        private static readonly object _lockObj;        static Singleton()        {            _lockObj = new object();        }        public static T Self        {            get            {                if (_self == null)                {                    lock (_lockObj)                    {                        if (_self == null)                        {                            _self = (default(T) == null) ? Activator.CreateInstance<T>() : default(T);                        }                    }                }                return _self;            }        }    }    public class SingletonMono<T> : MonoBehaviour where T : MonoBehaviour     {        private static T _self;        private static readonly object _lockObj;        static SingletonMono()        {            _lockObj = new object();        }        public static T Self        {            get            {                if (_self == null)                {                    lock (_lockObj)                    {                        if (_self == null)                        {                            var go = new GameObject(typeof(T).ToString()) ;                            _self = go.AddComponent<T>();                            DontDestroyOnLoad(go);                        }                    }                }                return _self;            }        }    }}
//********************************************************************// 文件名: ABMgrTest.cs// 描述: // 作者: 李伟// 创建时间: 2015-07-15////********************************************************************using SK;using UnityEngine;using System.Collections;using System.Collections.Generic;public class ABMgrTest : MonoBehaviour{    void Start()    {        Load.LoadAssetBundlesManifest(LoadAssetBundlesManifestCallback);    }    void LoadAssetBundlesManifestCallback()    {        Load logoLoad = new Load("data", logoLoadCallback);        logoLoad.BeginLoad();        Load boxLoad = new Load("box", boxCallback);        boxLoad.BeginLoad();    }    void logoLoadCallback()    {        if (!ABMgr.Self.IsContainItem("data")) return;        GameObject obj = ABMgr.Self.GetItemChild("data", "pre_cryWolfLogo") as GameObject;        Instantiate(obj);        GameObject obj2 = ABMgr.Self.GetItemChild("data", "pre_cryWolfLogo_url") as GameObject;        Instantiate(obj2);    }    void boxCallback()    {        if (!ABMgr.Self.IsContainItem("box")) return;        GameObject obj = ABMgr.Self.GetItemChild("box", "box") as GameObject;        Instantiate(obj);    }}
3 1