一、读取AssetBundle 依赖关系清单文件。(Windows.Manifest)
/***
*
* Title: "AssetBundle简单框架"项目
* 辅助类:
* 读取AssetBundle 依赖关系清单文件。(Windows.Manifest)
*
* Description:
* 功能:
*
* Author: Liuguozhu
*
* Date: 2017.10
*
* Modify:
*
*/
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace ABFW
{
public class ABManifestLoader : System.IDisposable
{
//本类实例
private static ABManifestLoader _Instance;
//Assetbundle (清单文件) 系统类
private AssetBundleManifest _ManifestObj;
//AssetBundle 清单文件的路径
private string _StrManifestPath;
//读取AB清单文件的AssetBundel
private AssetBundle _ABReadManifest;
//是否加载(Manifest )完成
private bool _IsLoadFinish;
/* 只读属性*/
public bool IsLoadFinish
{
get { return _IsLoadFinish; }
}
//构造函数
private ABManifestLoader()
{
//确定清单文件WWW下载路径
_StrManifestPath = PathTools.GetWWWPath() + "/" + PathTools.GetPlatformName();
_ManifestObj = null;
_ABReadManifest = null;
_IsLoadFinish = false;
}
/// <summary>
/// 获取本类实例
/// </summary>
/// <returns></returns>
public static ABManifestLoader GetInstance()
{
if (_Instance==null)
{
_Instance = new ABManifestLoader();
}
return _Instance;
}
//加载Manifest 清单文件
public IEnumerator LoadMainifestFile()
{
using (WWW www=new WWW(_StrManifestPath))
{
yield return www;
if (www.progress >= 1)
{
//加载完成,获取AssetBundle 实例
AssetBundle abObj = www.assetBundle;
if (abObj != null)
{
_ABReadManifest = abObj;
//读取清单文件资源。(读取到系统类的实例中。)
_ManifestObj = _ABReadManifest.LoadAsset(ABDefine.ASSETBUNDLE_MANIFEST) as AssetBundleManifest;
//本次加载与读取清单文件完毕。
_IsLoadFinish = true;
}
else {
Debug.Log(GetType()+ "/LoadMainifestFile()/WWW下载出错,请检查! _StrManifestPath="+ _StrManifestPath+" 错误信息: "+www.error);
}
}
}
}
/// <summary>
/// 获取AssetBundleManifest 系统类实例
/// </summary>
/// <returns></returns>
public AssetBundleManifest GetABManifest()
{
if (_IsLoadFinish)
{
if (_ManifestObj != null)
{
return _ManifestObj;
}
else
{
Debug.Log(GetType() + "/GetABManifest()/_ManifestObj==null ! 请检查");
}
}
else {
Debug.Log(GetType() + "/GetABManifest()/_IsLoadFinish==false , Manifest没有加载完毕,请检查!");
}
return null;
}
/// <summary>
/// 获取AssetBundleManifest(系统类) 指定包名称依赖项
/// </summary>
/// <param name="abName">AB包名称</param>
/// <returns></returns>
public string[] RetrivalDependce(string abName)
{
if (_ManifestObj!=null && !string.IsNullOrEmpty(abName))
{
return _ManifestObj.GetAllDependencies(abName);
}
return null;
}
/// <释放本类资源summary>
/// 释放本类资源
/// </summary>
public void Dispose()
{
if (_ABReadManifest!=null)
{
_ABReadManifest.Unload(true);
}
}
}
}
二、AssetBundle 关系类
/***
*
* Title: "AssetBundle简单框架"项目
* 工具辅助类:
* AssetBundle 关系类
*
* Description:
* 功能:
* 1: 存储指定AB包的所有依赖关系包
* 2: 存储指定AB包所有的引用关系包
*
* Author: Liuguozhu
*
* Date: 2017.10
*
* Modify:
*
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace ABFW
{
public class ABRelation
{
//当前AsseetBundel 名称
private string _ABName;
//本包所有的依赖包集合
private List<string> _LisAllDependenceAB;
//本包所有的引用包集合
private List<string> _lisAllReferenceAB;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="abName"></param>
public ABRelation(string abName)
{
if (!string.IsNullOrEmpty(abName))
{
_ABName = abName;
}
_LisAllDependenceAB = new List<string>();
_lisAllReferenceAB = new List<string>();
}
/* 依赖关系 */
/// <summary>
/// 增加依赖关系
/// </summary>
/// <param name="abName">AssetBundle 包名称</param>
public void AddDependence(string abName)
{
if (!_LisAllDependenceAB.Contains(abName))
{
_LisAllDependenceAB.Add(abName);
}
}
/// <summary>
/// 移除依赖关系
/// </summary>
/// <param name="abName">移除的包名称</param>
/// <returns>
/// true; 此AssetBundel 没有依赖项
/// false; 此AssetBundel 还有其他的依赖项
///
/// </returns>
public bool RemoveDependece(string abName)
{
if (_LisAllDependenceAB.Contains(abName))
{
_LisAllDependenceAB.Remove(abName);
}
if (_LisAllDependenceAB.Count > 0)
{
return false;
}
else {
return true;
}
}
//获取所有依赖关系
public List<string> GetAllDependence()
{
return _LisAllDependenceAB;
}
/* 引用关系 */
/// <summary>
/// 引用依赖关系
/// </summary>
/// <param name="abName">AssetBundle 包名称</param>
public void AddReference(string abName)
{
if (!_lisAllReferenceAB.Contains(abName))
{
_lisAllReferenceAB.Add(abName);
}
}
/// <summary>
/// 移除引用关系
/// </summary>
/// <param name="abName">移除的包名称</param>
/// <returns>
/// true; 此AssetBundel 没有引用项
/// false; 此AssetBundel 还有其他的引用项
///
/// </returns>
public bool RemoveReference(string abName)
{
if (_lisAllReferenceAB.Contains(abName))
{
_lisAllReferenceAB.Remove(abName);
}
if (_lisAllReferenceAB.Count > 0)
{
return false;
}
else
{
return true;
}
}
//获取所有引用关系
public List<string> GetAllReference()
{
return _lisAllReferenceAB;
}
}
}
三、框架主流程(第4层): 所有“场景”的AssetBundle 管理。
/***
*
* Title: "AssetBundle简单框架"项目
* 框架主流程(第4层): 所有“场景”的AssetBundle 管理。
*
* Description:
* 功能:
* 1: 提取“Menifest 清单文件”,缓存本脚本。
* 2:以“场景”为单位,管理整个项目中所有的AssetBundle 包。
*
* Author: Liuguozhu
*
* Date: 2017.10
*
* Modify:
*
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace ABFW
{
public class AssetBundleMgr:MonoBehaviour
{
//本类实例
private static AssetBundleMgr _Instance;
//场景集合
private Dictionary<string, MultiABMgr> _DicAllScenes = new Dictionary<string, MultiABMgr>();
//AssetBundle (清单文件) 系统类
private AssetBundleManifest _ManifestObj = null;
private AssetBundleMgr(){}
//得到本类实例
public static AssetBundleMgr GetInstance()
{
if (_Instance==null)
{
_Instance = new GameObject("_AssetBundleMgr").AddComponent<AssetBundleMgr>();
}
return _Instance;
}
void Awake()
{
//加载Manifest清单文件
StartCoroutine(ABManifestLoader.GetInstance().LoadMainifestFile());
}
/// <summary>
/// 下载AssetBundel 指定包
/// </summary>
/// <param name="scenesName">场景名称</param>
/// <param name="abName">AssetBundle 包名称</param>
/// <param name="loadAllCompleteHandle">委托: 调用是否完成</param>
/// <returns></returns>
public IEnumerator LoadAssetBundlePack(string scenesName, string abName, DelLoadComplete loadAllCompleteHandle)
{
//参数检查
if (string.IsNullOrEmpty(scenesName) || string.IsNullOrEmpty(abName))
{
Debug.LogError(GetType()+ "/LoadAssetBundlePack()/ScenesName Or abName is null ,请检查!");
yield return null;
}
//等待Manifest清单文件加载完成
while (!ABManifestLoader.GetInstance().IsLoadFinish)
{
yield return null;
}
_ManifestObj = ABManifestLoader.GetInstance().GetABManifest();
if (_ManifestObj==null)
{
Debug.LogError(GetType() + "/LoadAssetBundlePack()/_ManifestObj is null ,请先确保加载Manifest清单文件!");
yield return null;
}
//把当前场景加入集合中。
if (!_DicAllScenes.ContainsKey(scenesName))
{
MultiABMgr multiMgrObj = new MultiABMgr(scenesName,abName, loadAllCompleteHandle);
_DicAllScenes.Add(scenesName, multiMgrObj);
}
//调用下一层(“多包管理类”)
MultiABMgr tmpMultiMgrObj = _DicAllScenes[scenesName];
if (tmpMultiMgrObj==null)
{
Debug.LogError(GetType() + "/LoadAssetBundlePack()/tmpMultiMgrObj is null ,请检查!");
}
//调用“多包管理类”的加载指定AB包。
yield return tmpMultiMgrObj.LoadAssetBundeler(abName);
}//Method_end
/// <summary>
/// 加载(AB 包中)资源
/// </summary>
/// <param name="scenesName">场景名称</param>
/// <param name="abName">AssetBundle 包名称</param>
/// <param name="assetName">资源名称</param>
/// <param name="isCache">是否使用缓存</param>
/// <returns></returns>
public UnityEngine.Object LoadAsset(string scenesName, string abName, string assetName ,bool isCache)
{
if (_DicAllScenes.ContainsKey(scenesName))
{
MultiABMgr multObj = _DicAllScenes[scenesName];
return multObj.LoadAsset(abName, assetName, isCache);
}
Debug.LogError(GetType()+ "/LoadAsset()/找不到场景名称,无法加载(AB包中)资源,请检查! scenesName="+ scenesName);
return null;
}
/// <summary>
/// 释放资源。
/// </summary>
/// <param name="scenesName">场景名称</param>
public void DisposeAllAssets(string scenesName)
{
if (_DicAllScenes.ContainsKey(scenesName))
{
MultiABMgr multObj = _DicAllScenes[scenesName];
multObj.DisposeAllAsset();
}
else {
Debug.LogError(GetType() + "/DisposeAllAssets()/找不到场景名称,无法释放资源,请检查! scenesName=" + scenesName);
}
}
}//Class_end
}
四、第1层: AB(AssetBundle)资源加载类
/***
*
* Title: "AssetBundle简单框架"项目
* 框架主流程:
* 第1层: AB(AssetBundle)资源加载类
*
*
* Description:
* 功能:
* 1: 管理与加载指定AB的资源。
* 2: 加载具有“缓存功能”的资源,带选用参数。
* 3: 卸载、释放AB资源。
* 4: 查看当前AB资源。
*
* Author: Liuguozhu
*
* Date: 2017.10
*
* Modify:
*
*/
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace ABFW
{
public class AssetLoader : System.IDisposable
{
//当前Assetbundle
private AssetBundle _CurrentAssetBundle;
//缓存容器集合
private Hashtable _Ht;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="abObj">给定WWW加载的AssetBundle 实例</param>
public AssetLoader(AssetBundle abObj)
{
if (abObj != null)
{
_CurrentAssetBundle = abObj;
_Ht = new Hashtable();
}
else {
Debug.Log(GetType()+"/ 构造函数 AssetBundle()/ 参数 abObj==null! ,请检查");
}
}
/// <summary>
/// 加载当前包中指定的资源
/// </summary>
/// <param name="assetName">资源的名称</param>
/// <param name="isCache">是否开启缓存</param>
/// <returns></returns>
public UnityEngine.Object LoadAsset(string assetName,bool isCache=false)
{
return LoadResource<UnityEngine.Object>(assetName, isCache);
}
/// <summary>
/// 加载当前AB包的资源,带缓存
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="assetName">资源的名称</param>
/// <param name="isCache">是否需要缓存处理</param>
/// <returns></returns>
private T LoadResource<T>(string assetName,bool isCache) where T : UnityEngine.Object
{
//是否缓存集合已经存在
if (_Ht.Contains(assetName))
{
return _Ht[assetName] as T;
}
//正式加载
T tmpTResource=_CurrentAssetBundle.LoadAsset<T>(assetName);
//加入缓存集合
if (tmpTResource != null && isCache)
{
_Ht.Add(assetName, tmpTResource);
} else if (tmpTResource==null)
{
Debug.LogError(GetType()+ "/LoadResource<T>()/参数 tmpTResources==null, 请检查!");
}
return tmpTResource;
}
/// <summary>
/// 卸载指定的资源
/// </summary>
/// <param name="asset">资源名称</param>
/// <returns></returns>
public bool UnLoadAsset(UnityEngine.Object asset)
{
if(asset!=null)
{
Resources.UnloadAsset(asset);
return true;
}
Debug.LogError(GetType()+ "/UnLoadAsset()/参数 asset==null ,请检查!");
return false;
}
/// <summary>
/// 释放当前AssetBundle内存镜像资源
/// </summary>
public void Dispose()
{
_CurrentAssetBundle.Unload(false);
}
/// <summary>
/// 释放当前AssetBundle内存镜像资源,且释放内存资源。
/// </summary>
public void DisposeALL()
{
_CurrentAssetBundle.Unload(true);
}
/// <summary>
/// 查询当前AssetBundle中包含的所有资源名称。
/// </summary>
/// <returns></returns>
public string[] RetriveAllAssetName()
{
return _CurrentAssetBundle.GetAllAssetNames();
}
}
}
五、主流程(3层):(一个场景中)多个AssetBundle 包管理
/***
*
* Title: "AssetBundle简单框架"项目
* 主流程(3层):(一个场景中)多个AssetBundle 包管理
*
* Description:
* 功能:
* 1: 获取AB包之间的依赖与引用关系。
* 2: 管理AssetBundle包之间的自动连锁(递归)加载机制
*
* Author: Liuguozhu
*
* Date: 2017.10
*
* Modify:
*
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace ABFW
{
public class MultiABMgr
{
//(下层)引用类: "单个AB包加载实现类"
private SingleABLoader _CurrentSinglgABLoader;
//“AB包实现类”缓存集合(作用: 缓存AB包,防止重复加载,即: “AB包缓存集合”)
private Dictionary<string, SingleABLoader> _DicSingleABLoaderCache;
//当前场景(调试使用)
private string _CurrentScenesName;
//当前AssetBundle 名称
private string _CurrentABName;
//AB包与对应依赖关系集合
private Dictionary<string, ABRelation> _DicABRelation;
//委托: 所有AB包加载完成。
private DelLoadComplete _LoadAllABPackageCompleteHandel;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="scenesName">场景名称</param>
/// <param name="abName">AB包名称</param>
/// <param name="loadAllABPackCompleteHandle">(委托)是否调用完成</param>
public MultiABMgr(string scenesName,string abName,DelLoadComplete loadAllABPackCompleteHandle)
{
_CurrentScenesName = scenesName;
_CurrentABName = abName;
_DicSingleABLoaderCache = new Dictionary<string, SingleABLoader>();
_DicABRelation = new Dictionary<string, ABRelation>();
//委托
_LoadAllABPackageCompleteHandel = loadAllABPackCompleteHandle;
}
/// <summary>
/// 完成指定AB包调用
/// </summary>
/// <param name="abName">AB包名称</param>
private void CompleteLoadAB(string abName)
{
Debug.Log(GetType() + "/当前完成abName: " + abName + " 包的加载");
if (abName.Equals(_CurrentABName))
{
if (_LoadAllABPackageCompleteHandel!=null)
{
_LoadAllABPackageCompleteHandel(abName);
}
}
}
/// <summary>
/// 加载AB包
/// </summary>
/// <param name="abName">AssetBundle 名称</param>
/// <returns></returns>
public IEnumerator LoadAssetBundeler(string abName)
{
//AB包关系的建立
if (!_DicABRelation.ContainsKey(abName))
{
ABRelation abRelationObj = new ABRelation(abName);
_DicABRelation.Add(abName, abRelationObj);
}
ABRelation tmpABRelationObj = _DicABRelation[abName];
//得到指定AB包所有的依赖关系(查询Manifest清单文件)
string[] strDependeceArray = ABManifestLoader.GetInstance().RetrivalDependce(abName);
foreach (string item_Depence in strDependeceArray)
{
//添加“依赖”项
tmpABRelationObj.AddDependence(item_Depence);
//添加“引用”项 (递归调用)
yield return LoadReference(item_Depence, abName);
}
//真正加载AB包
if (_DicSingleABLoaderCache.ContainsKey(abName))
{
yield return _DicSingleABLoaderCache[abName].LoadAssetBundle();
}
else {
_CurrentSinglgABLoader = new SingleABLoader(abName, CompleteLoadAB);
_DicSingleABLoaderCache.Add(abName, _CurrentSinglgABLoader);
yield return _CurrentSinglgABLoader.LoadAssetBundle();
}
}//Method_end
/// <summary>
/// 加载引用AB包
/// </summary>
/// <param name="abName">AB包名称</param>
/// <param name="refABName">被引用AB包名称</param>
/// <returns></returns>
private IEnumerator LoadReference(string abName,string refABName)
{
//AB包已经加载
if (_DicABRelation.ContainsKey(abName))
{
ABRelation tmpABRelationObj = _DicABRelation[abName];
//添加AB包引用关系(被依赖)
tmpABRelationObj.AddReference(refABName);
}
else {
ABRelation tmpABRelationObj = new ABRelation(abName);
tmpABRelationObj.AddReference(refABName);
_DicABRelation.Add(abName, tmpABRelationObj);
//开始加载依赖的包(这是一个递归调用)
yield return LoadAssetBundeler(abName);
}
}
/// <summary>
/// 加载(AB包中)资源
/// </summary>
/// <param name="abName">AssetBunlde 名称</param>
/// <param name="assetName">资源名称</param>
/// <param name="isCache">是否使用(资源)缓存</param>
/// <returns></returns>
public UnityEngine.Object LoadAsset(string abName, string assetName, bool isCache)
{
foreach (string item_abName in _DicSingleABLoaderCache.Keys)
{
if (abName== item_abName)
{
return _DicSingleABLoaderCache[item_abName].LoadAsset(assetName, isCache);
}
}
Debug.LogError(GetType()+ "/LoadAsset()/找不到AsetBunder包,无法加载资源,请检查! abName="+ abName+ " assetName="+ assetName);
return null;
}
/// <summary>
/// 释放本场景中所有的资源
/// </summary>
public void DisposeAllAsset()
{
try
{
//逐一释放所有加载过的AssetBundel 包中的资源
foreach (SingleABLoader item_sABLoader in _DicSingleABLoaderCache.Values)
{
item_sABLoader.DisposeALL();
}
}
finally
{
_DicSingleABLoaderCache.Clear();
_DicSingleABLoaderCache = null;
//释放其他对象占用资源
_DicABRelation.Clear();
_DicABRelation = null;
_CurrentABName = null;
_CurrentScenesName = null;
_LoadAllABPackageCompleteHandel = null;
//卸载没有使用到的资源
Resources.UnloadUnusedAssets();
//强制垃圾收集
System.GC.Collect();
}
}
}
}
六、第2层: WWW 加载AssetBundel
/***
*
* Title: "AssetBundle简单框架"项目
* 框架主流程:
* 第2层: WWW 加载AssetBundel
*
* Description:
* 功能:
*
* Author: Liuguozhu
*
* Date: 2017.10
*
* Modify:
*
*/
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace ABFW
{
public class SingleABLoader: System.IDisposable
{
//引用类: 资源加载类
private AssetLoader _AssetLoader;
//委托:
private DelLoadComplete _LoadCompleteHandle;
//AssetBundle 名称
private string _ABName;
//AssetBundle 下载路径
private string _ABDownLoadPath;
//构造函数
public SingleABLoader(string abName,DelLoadComplete loadComplete)
{
_AssetLoader = null;
_ABName = abName;
//委托初始化
_LoadCompleteHandle = loadComplete;
//AB包下载路径(初始化)
_ABDownLoadPath = PathTools.GetWWWPath() + "/" + _ABName;
}
//加载AssetBundle 资源包
public IEnumerator LoadAssetBundle()
{
using (WWW www=new WWW(_ABDownLoadPath))
{
yield return www;
//WWW下载AB包完成
if (www.progress>=1)
{
//获取AssetBundle的实例
AssetBundle abObj = www.assetBundle;
if (abObj!=null)
{
//实例化引用类
_AssetLoader = new AssetLoader(abObj);
//AssetBundle 下载完毕,调用委托
if (_LoadCompleteHandle!=null)
{
_LoadCompleteHandle(_ABName);
}
}
else {
Debug.LogError(GetType()+ "/LoadAssetBundle()/WWW 下载出错,请检查! AssetBundle URL: "+ _ABDownLoadPath+" 错误信息: "+www.error);
}
}
}//using_end
}
/// <summary>
/// 加载(AB包内)资源
/// </summary>
/// <param name="assetName"></param>
/// <param name="isCache"></param>
/// <returns></returns>
public UnityEngine.Object LoadAsset(string assetName,bool isCache)
{
if (_AssetLoader!=null)
{
return _AssetLoader.LoadAsset(assetName,isCache);
}
Debug.LogError(GetType()+ "/LoadAsset()/ 参数_AssetLoader==null ,请检查!");
return null;
}
/// <summary>
/// 卸载(AB包中)资源
/// </summary>
/// <param name="asset"></param>
public void UnLoadAsset(UnityEngine.Object asset)
{
if (_AssetLoader != null)
{
_AssetLoader.UnLoadAsset(asset);
}
else {
Debug.LogError(GetType()+ "/UnLoadAsset()/参数 _AssetLoader==Null , 请检查!");
}
}
/// <summary>
/// 释放资源
/// </summary>
public void Dispose()
{
if (_AssetLoader != null)
{
_AssetLoader.Dispose();
_AssetLoader = null;
}
else
{
Debug.LogError(GetType() + "/Dispose()/参数 _AssetLoader==Null , 请检查!");
}
}
/// <summary>
/// 释放当前AssetBundle资源包,且卸载所有资源
/// </summary>
public void DisposeALL()
{
if (_AssetLoader != null)
{
_AssetLoader.DisposeALL();
_AssetLoader = null;
}
else
{
Debug.LogError(GetType() + "/DisposeALL()/参数 _AssetLoader==Null , 请检查!");
}
}
/// <summary>
/// 查询当前AssetBundle包中所有的资源
/// </summary>
/// <returns></returns>
public string[] RetrivalAllAssetName()
{
if (_AssetLoader != null)
{
return _AssetLoader.RetriveAllAssetName();
}
Debug.LogError(GetType() + "/RetrivalAllAssetName()/参数 _AssetLoader==Null , 请检查!");
return null;
}
}
}