Unity AssetBundles资源加载管理器
实现了AB包管理器
目的: 让外部更方便地进行资源加载(同步加载/异步加载)
技术包含:
- AB包相关API
- 单例模式
- 委托(Lambda)表达式
- 协程
- 字典
csharp
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.Events;
/// <summary>
/// AB 包管理器
/// 目的: 让外部更方便地进行资源加载
/// 包含
/// 1. AB包相关API
/// 2. 单例模式
/// 3. 委托(Lambda)表达式
/// 4. 协程
/// 5. 字典
/// </summary>
public class ABMgr : SingletonAutoMono<ABMgr>
{
//主包
private AssetBundle mainAB = null;
//依赖包获取的配置文件
private AssetBundleManifest manifest= null;
//字典 用字典来存储 加载过的AB包
private Dictionary<string, AssetBundle> abDic = new Dictionary<string, AssetBundle>();
//AB包存放路径
private string PathUrl
{
get
{
return Application.streamingAssetsPath+"/";
}
}
//主包名
private string MainABName
{
get
{
#if UNITY_IOS
return "IOS";
#elif UNITY_ANDROID
return "Android";
#else
return "PC";
#endif
}
}
/// <summary>
/// 加载ab包
/// </summary>
/// <param name="abname"></param>
private void LoadAB(string abname)
{
//加载AB包
if (mainAB == null)
{
mainAB = AssetBundle.LoadFromFile(PathUrl + MainABName);
manifest = mainAB.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
}
//获取abname包的依赖信息,根据依赖信息添加依赖包
AssetBundle ab = null;
string[] strs = manifest.GetAllDependencies(abname);
for (int i = 0; i < strs.Length; i++)
{
//判断包是否加载过了
if (!abDic.ContainsKey(strs[i]))
{
ab = AssetBundle.LoadFromFile(PathUrl + strs[i]);
abDic.Add(strs[i], ab);
}
}
//加载资源来源包,如果没有加载过再加载
if (!abDic.ContainsKey(abname))
{
ab = AssetBundle.LoadFromFile(PathUrl + abname);
abDic.Add(abname, ab);
}
}
//同步加载 根据名字
public Object LoadRes(string abname,string resname)
{
//加载ab包
LoadAB(abname);
//加载资源
//为了方便外面加载 判断资源是否为GameObect
//如果是 直接实例化 再返回给外部
Object obj = abDic[abname].LoadAsset(resname);
if (obj is GameObject)
{
return Instantiate(obj);
}
else return obj;
}
//同步加载 根据type
public Object LoadRes(string abname, string resname,System.Type type)
{
//加载ab包
LoadAB(abname);
//加载资源
//为了方便外面加载 判断资源是否为GameObect
//如果是 直接实例化 再返回给外部
Object obj = abDic[abname].LoadAsset(resname,type);
if (obj is GameObject)
{
return Instantiate(obj);
}
else return obj;
}
//同步加载 泛型
public T LoadRes<T>(string abname, string resname) where T: Object
{
//加载ab包
LoadAB(abname);
//加载资源
//为了方便外面加载 判断资源是否为GameObect
//如果是 直接实例化 再返回给外部
T obj = abDic[abname].LoadAsset<T>(resname);
if (obj is GameObject)
{
return Instantiate(obj);
}
else return obj;
}
/// <summary>
/// 异步加载(Async) 根据名字
/// 加载AB包没有使用异步
/// 而是加载AB包中的asset资源的时候使用异步
/// </summary>
/// <param name="abname"></param>
public void LoadResAsync(string abname, string resname,UnityAction<Object> callBack)
{
StartCoroutine(ReallyLoadAsync(abname,resname,callBack));
}
private IEnumerator ReallyLoadAsync(string abname,string resname,UnityAction<Object> callBack)
{
//加载AB包
LoadAB(abname);
//创建请求 从AB包加载资源
AssetBundleRequest abr = abDic[abname].LoadAssetAsync(resname);
//等待abr加载结束
yield return abr;
//abr.asset 为加载的资源
if(abr.asset is GameObject)
{
//abr如果是GameObject 实例化
callBack(Instantiate(abr.asset));
}else
{
callBack(abr.asset);
}
}
/// <summary>
/// 异步加载(Async) 根据type
/// </summary>
/// <param name="abname"></param>
public void LoadResAsync(string abname, string resname,System.Type type, UnityAction<Object> callBack)
{
StartCoroutine(ReallyLoadAsync(abname, resname,type, callBack));
}
private IEnumerator ReallyLoadAsync(string abname, string resname, System.Type type,UnityAction<Object> callBack)
{
//加载AB包
LoadAB(abname);
//创建请求 从AB包加载资源
AssetBundleRequest abr = abDic[abname].LoadAssetAsync(resname,type);
//等待abr加载结束
yield return abr;
//abr.asset 为加载的资源
if (abr.asset is GameObject)
{
//abr如果是GameObject 实例化
callBack(Instantiate(abr.asset));
}
else
{
callBack(abr.asset);
}
}
/// <summary>
/// 异步加载(Async) 泛型
/// </summary>
/// <param name="abname"></param>
public void LoadResAsync<T>(string abname, string resname, UnityAction<T> callBack) where T : Object
{
// public delegate void UnityAction<T0>(T0 arg0);
//其中UnityAciton是有着一个参数(T0)的委托
StartCoroutine(ReallyLoadAsync<T>(abname, resname, callBack));
}
private IEnumerator ReallyLoadAsync<T>(string abname, string resname, UnityAction<T> callBack) where T: Object
{
//加载AB包
LoadAB(abname);
//创建请求 从AB包加载资源
AssetBundleRequest abr = abDic[abname].LoadAssetAsync<T>(resname);
//等待abr加载结束
yield return abr;
//abr.asset 为加载的资源
if (abr.asset is GameObject)
{
//abr如果是GameObject 实例化
//最后回调函数(函数指针,函数作为参数)调用委托
callBack(Instantiate(abr.asset) as T);
}
else
{
callBack(abr.asset as T);
}
}
//单个包卸载
public void Unload(string abname)
{
if (abDic.ContainsKey(abname))
{
abDic[abname].Unload(false);
abDic.Remove(abname);
}
}
//所有包卸载
public void ClearAB()
{
//卸载所有AssetBundles(UnloadAll)
AssetBundle.UnloadAllAssetBundles(false);
//清空字典
abDic.Clear();
//主包和配置文件置空
mainAB = null;
manifest = null;
}
}