一、AssetBundle整体管理
《1》AssetBundle框架的整体管理包含两大部分
①主程序的AssetBundleMgr脚本,通过调用辅助类“ABManifestLoader”来读取Untiy提供的Manifest清单文件。
②主程序的MutiABMgr脚本,通过获取Manifest清单文件,循环遍历需要加载AB包所有的底层依赖包。然后给每个AB包都记录相关依赖于引用关系,这些关系都记录在对应的ABRelation对象中。
框架资源包地址:https://download.csdn.net/download/xiaochenxihua/10761774
/***
*
* Title: "AssetBundle工具包"项目
* 辅助类: 读取AssetBundles 依赖关系文件:Win.Manifest
*
* Description:
* 功能:
* Win.Manifest 文件是Unity提供的一份确定所有
* Assetbundle 包文件所有依赖关系的清单文件。
*
* Date: 2018
*
* Version: 1.0
*
* Modify Recorder:
*
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace ABTools
{
public class ABManifestLoader:System.IDisposable {
//本类实例
private static ABManifestLoader _Instance;
//AssetBundle(清单文件)系统类
private AssetBundleManifest _ManifestObj;
//AssetBundle 清单文件路径
private string _StrManifestPath;
//读取Manifest清单文件的AssetBundle
private AssetBundle _ABReadManifest;
//是否加载完成
private bool _IsLoadFinish;
/* 只读属性 */
public bool IsLoadFinish{
get { return _IsLoadFinish; }
}
#region
///
/// 构造函数
///
private ABManifestLoader()
{
//确定清单WWW下载路径
_StrManifestPath = PathTools.GetWWWPath() + "/" + PathTools.GetPlatformName();
_ManifestObj = null;
_ABReadManifest = null;
_IsLoadFinish = false;
}
///
/// 得到本类实例
///
///
public static ABManifestLoader GetInstance()
{
if(_Instance==null)
{
_Instance = new ABManifestLoader();
}
return _Instance;
}
#endregion
/// 加载Manifest清单文件
public IEnumerator LoadManifestFile(){
using (WWW www = new WWW(_StrManifestPath)){
yield return www;
if (www.progress >= 1){
//加载完成,获取AssetBundel实例
AssetBundle abObj = www.assetBundle;
if (abObj != null){
_ABReadManifest = abObj;
_ManifestObj=_ABReadManifest.LoadAsset(ABDefine.ASSETBUNDLE_MANIFEST) as AssetBundleManifest;
_IsLoadFinish = true;
}
else{
Debug.LogError(GetType() + "/LoadManifestFile()/WWW 下载出错,请检查 AssetBundle URL :" + _StrManifestPath + " 错误信息: " + www.error);
}
}
}//using_end
}
///
/// 返回"AssetBundleManifest"系统类实例
///
///
public AssetBundleManifest GetABManifest()
{
if (_IsLoadFinish)
{
if (_ManifestObj != null)
{
return _ManifestObj;
}
else {
Debug.Log(GetType() + "/GetABManifest()/_ManifestObj==null 。请检查原因!");
}
}
else {
Debug.Log(GetType() + "/GetABManifest()/Manifest没有加载完毕,请检查原因!");
}
return null;
}
///
/// 获取指定AssetBundle包所有依赖项
///
///
///
public string[] RetrivalDependences(string abName)
{
if (_ManifestObj != null && !string.IsNullOrEmpty(abName))
{
return _ManifestObj.GetAllDependencies(abName);
}
return null;
}
///
/// 释放资源(卸载Manifest所有资源)
///
public void Dispose()
{
if (_ABReadManifest!=null)
{
_ABReadManifest.Unload(true);
}
}
}//Class_end
}
/***
*
* Title: "AssetBundle工具包"项目
* 辅助类; AssetBundle 关系类
*
* Description:
* 功能:
* 1:确定指定AssetBundle 类的依赖包。
* 2:确定指定AssetBundle 类的引用包(被依赖包)
*
* Date: 2018
*
* Version: 1.0
*
* Modify Recorder:
*
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace ABTools
{
public class ABRelation
{
//AssetBundle 名称
private string _ABName;
//所有依赖包名
private List _LisAllDependenceAB;
//所有引用包名
private List _LisALLReferenceAB;
/// 构造函数
public ABRelation(string abName)
{
_ABName = abName;
_LisAllDependenceAB = new List();
_LisALLReferenceAB = new List();
}
/* 依赖关系 */
#region 依赖关系
///
/// 增加依赖关系
///
/// Assetbundle 名称
public void AddDependence(string abName)
{
if (!_LisAllDependenceAB.Contains(abName))
{
_LisAllDependenceAB.Add(abName);
}
}
///
/// 移除依赖关系
///
///
///
/// true: 此AssetBundle没有依赖项
/// false: 此AssetBundle还有其他的依赖项
///
public bool RemoveDependence(string abName)
{
if (_LisAllDependenceAB.Contains(abName))
{
_LisAllDependenceAB.Remove(abName);
}
if (_LisAllDependenceAB.Count > 0)
{
return false;
}
else
{
return true;
}
}
///
/// 获取所有的依赖关系
///
///
public List GetAllDependences()
{
return _LisAllDependenceAB;
}
#endregion
/* 引用关系 */
#region 引用关系
///
/// 增加引用关系
///
///
public void AddReference(string abName)
{
if (!_LisALLReferenceAB.Contains(abName))
{
_LisALLReferenceAB.Add(abName);
}
}
///
/// 移除引用关系
///
///
///
/// true: 此AssetBundle没有引用项
/// false: 此AssetBundle还有其他的引用项
///
public bool RemoveReference(string abName)
{
if (_LisALLReferenceAB.Contains(abName))
{
_LisALLReferenceAB.Remove(abName);
}
if (_LisALLReferenceAB.Count > 0)
{
return false;
}
else
{
return true;
}
}
///
/// 获取所有的引用关系(集合)
///
///
public List GetAllReference()
{
return _LisALLReferenceAB;
}
#endregion
}//Class_end
}
/***
*
* Title: "AssetBundle工具包"项目
* 第4层(最后层): 所有“场景”的AssetBundle的管理
*
* Description:
* 功能:
* 1:以“场景”为单位,管理整个项目所有的AssetBundle 包。
* 2:提取“Menifest清单文件”,缓存本类。
*
* Date: 2018
*
* Version: 1.0
*
* Modify Recorder:
*
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace ABTools
{
public class AssetBundleMgr: MonoBehaviour{
//本类实例
private static AssetBundleMgr _Instance;
//场景集合
private Dictionary _DicAllScenes = new Dictionary();
//AssetBundle(清单文件)系统类(包含本项目所有依赖项)
private AssetBundleManifest _ManifestObj=null;
#region
private AssetBundleMgr() { }
///
/// 得到本类实例
///
///
public static AssetBundleMgr GetInstance()
{
if (_Instance==null)
{
_Instance = new GameObject("_AssetBundleMgr").AddComponent();
}
return _Instance;
}
private void Awake()
{
// 加载Manifest清单文件
StartCoroutine(ABManifestLoader.GetInstance().LoadManifestFile());
}
#endregion
///
/// 下载AssetBundle指定包
///
/// 场景名称
/// AssetBundle名称
/// AssetBundle名称
public IEnumerator LoadAssetBundlePackage(string sceneName,string abName,DelLoadComplete loadAllABCompleteHandle)
{
//参数检查
if (string.IsNullOrEmpty(sceneName) || string.IsNullOrEmpty(abName))
{
Debug.LogError(GetType()+ "/LoadAssetBundlePackage()/scenenName Or abName is Null ,请检查!");
yield return null;
}
//等待Manifest清单加载完成
while (!ABManifestLoader.GetInstance().IsLoadFinish)
yield return null;
//获取“AssetBundle(清单文件)系统类”
_ManifestObj = ABManifestLoader.GetInstance().GetABManifest();
//参数检查
if (_ManifestObj==null)
{
Debug.LogError(GetType() + "/LoadAssetBundlePackage()/_ManifestObj==null,请先确保加载Manifest清单文件!");
yield return null;
}
//如果不包含指定场景,则先创建
if (!_DicAllScenes.ContainsKey(sceneName))
{
CreateScenesAB(sceneName,abName, loadAllABCompleteHandle);
}
//调用下一层(“多AssetBundle管理”类)
MultiABMgr tmpMultiABMgrObj =_DicAllScenes[sceneName];
if (tmpMultiABMgrObj==null)
{
Debug.LogError(GetType()+ "/LoadAssetBundlePackage()/tmpMultiABMgrObj==null , 请检查!");
}
yield return tmpMultiABMgrObj.LoadAssetBundles(abName);
}
///
/// 创建一个“场景AssetBundle”且加入集合中
///
///
private void CreateScenesAB(string scensName,string abName, DelLoadComplete loadAllABCompleteHandle)
{
MultiABMgr multiABMgeObj = new MultiABMgr(scensName, abName,loadAllABCompleteHandle);
_DicAllScenes.Add(scensName,multiABMgeObj);
}
///
/// 加载(AB包内)资源
///
/// 场景名称
/// AssetBundle 名称
/// 资源名称
/// 是否使用(资源)缓存
///
public UnityEngine.Object LoadAsset(string scenesName,string abName,string assetName, bool isCache)
{
if (_DicAllScenes.ContainsKey(scenesName))
{
MultiABMgr multiObj = _DicAllScenes[scenesName];
return multiObj.LoadAsset(abName,assetName,isCache);
}
Debug.LogError(GetType()+"/LoadAsset()/找不到场景: "+scenesName+" ,无法加载AssetBundle 资源,请检查!");
return null;
}
///
/// 释放一个场景中所有的资源
///
///
///
public void DisposeAllAssets(string scenesName)
{
if (_DicAllScenes.ContainsKey(scenesName))
{
MultiABMgr multiObj = _DicAllScenes[scenesName];
multiObj.DisposeAllAsset();
}
else {
Debug.LogError(GetType() + "/DisposeAllAsset()/找不到场景: " + scenesName + " ,无法释放资源,请检查!");
}
}
}//Class_end
}
/***
*
* Title: "AssetBundle工具包"项目
* 第3层: (一个场景中)多AssetBundle管理
*
* Description:
* 功能:
* 1:获得包之间的依赖关系。
* 2:管理具备依赖与引用关系的AssetBundle包的自动连锁加载机制。
*
*
* Date: 2018
*
* Version: 1.0
*
* Modify Recorder:
*
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace ABTools
{
public class MultiABMgr
{
//当前 "单个AB加载实现类"
private SingleABLoader _CurrentSingleABLoader;
//"单个AB加载实现类"缓存集合(作用: 缓存AB包,防止重复加载)
//第1个参数表示“AB包名称”,第2参数是“单个AB加载实现类”
private Dictionary _DicSingleABLoaderCache;
//当前场景名称
private string _CurrentScenesName;
//当前AssetBundle 名称
private string _CurrentABName;
//AB包名称与对应依赖关系集合
private Dictionary _DicABRelation;
//委托: 所有的AB包加载完成
private DelLoadComplete _LoadAllABPackageCompleteHandle;
///
/// 构造函数
///
/// 场景名称
/// AssetBundle名称
/// /// 委托:加载所有AB包完成
public MultiABMgr(string scenesName,string abName,DelLoadComplete loadAllABPackageCompletteHandle)
{
_CurrentScenesName = scenesName;
_CurrentABName = abName;
_DicSingleABLoaderCache = new Dictionary();
_DicABRelation = new Dictionary();
//委托:加载所有AB包完成
_LoadAllABPackageCompleteHandle=loadAllABPackageCompletteHandle;
}
///
/// 完成指定AB包的调用
///
///
private void CompletLoadAB(string abName)
{
if (abName.Equals(_CurrentABName))
{
if (_LoadAllABPackageCompleteHandle!=null)
{
_LoadAllABPackageCompleteHandle(abName);
}
}
}
///
/// 加载AB包
///
///
///
public IEnumerator LoadAssetBundles(string abName)
{
if (!_DicABRelation.ContainsKey(abName))
{
ABRelation abRelationObj = new ABRelation(abName);
_DicABRelation.Add(abName,abRelationObj);
}
ABRelation tmpABRelationObj = _DicABRelation[abName];
//得到指定AB包所有的依赖关系
string[] strDepencedArray = ABManifestLoader.GetInstance().RetrivalDependences(abName);
foreach (string item_Depence in strDepencedArray)
{
//添加“依赖”项
tmpABRelationObj.AddDependence(item_Depence);
//添加“引用”项
yield return LoadReference(item_Depence,abName);
}
//真正的AB包加载
if (_DicSingleABLoaderCache.ContainsKey(abName))
{
yield return _DicSingleABLoaderCache[abName].LoadAssetBundle();
}
else {
_CurrentSingleABLoader = new SingleABLoader(abName, CompletLoadAB);
_DicSingleABLoaderCache.Add(abName,_CurrentSingleABLoader);
yield return _CurrentSingleABLoader.LoadAssetBundle();
}
}//Method_end
///
/// 加载引用AB包
///
/// AB包名称
/// 引用AB包名称
///
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 LoadAssetBundles(abName);
}
}//Method_end
///
/// 加载(AB包内)资源
///
/// AssetBundle 名称
/// 资源名称
/// 是否使用(资源)缓存
///
public UnityEngine.Object LoadAsset(string abName, string assetName, bool isCache)
{
foreach (string item_AbName in _DicSingleABLoaderCache.Keys)
{
if(item_AbName==abName)
{
return _DicSingleABLoaderCache[item_AbName].LoadAsset(assetName,isCache);
}
}
Debug.LogError(GetType() + "/LoadAsset()/找不到Assetbundle 包,无法加载资源,请检查! abName= "+abName+ " assetName="+assetName);
return null;
}
///
/// 释放场景中所有资源
///
///
public void DisposeAllAsset()
{
//逐一释放所有加载过的AssetBundle包资源
try
{
foreach (SingleABLoader item_sABLoader in _DicSingleABLoaderCache.Values)
{
item_sABLoader.DisposeALL();
}
}
finally
{
_DicSingleABLoaderCache.Clear();
_DicSingleABLoaderCache = null;
/* 释放其他对象占用 */
_DicABRelation.Clear();
_DicABRelation = null;
_CurrentScenesName = null;
_CurrentABName = null;
_LoadAllABPackageCompleteHandle = null;
//卸载没有使用到的资源
Resources.UnloadUnusedAssets();
//强制垃圾收集
System.GC.Collect();
}
}
}//Class_end
}
注:本内容来自《Untiy3D/2D游戏开发从0到1》 第30章