您的位置:首页 > 移动开发 > Unity3D

Unity5 AssetBundle管理

2015-08-13 23:55 441 查看
//********************************************************************
// 文件名: 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>, IMgr
{
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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: