Unity AssetBundles资源加载管理器
实现了AB包管理器
目的: 让外部更方便地进行资源加载(同步加载/异步加载)
技术包含:
- AB包相关API
- 单例模式
- 委托(Lambda)表达式
- 协程
- 字典
AssetBundles工具下载地址
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_IOSreturn "IOS";#elif UNITY_ANDROIDreturn "Android";#elsereturn "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;}//同步加载 根据typepublic 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;}}