using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using Object = UnityEngine.Object;
public class AssetBundleMgr : MonoBehaviour
{
/// <summary>
/// AB 包存放路径
/// </summary>
private static readonly string AB_DIRECTORY = Application.streamingAssetsPath + "/";
/// <summary>
/// 主包名
/// </summary>
private static readonly string MAIN_AB_NAME = "StandaloneWindows";
/// <summary>
/// 主包
/// </summary>
private AssetBundle mainAB = null;
/// <summary>
/// 依赖包获取用的配置文件
/// </summary>
private AssetBundleManifest manifest = null;
/// <summary>
/// 存储加载过的 AB 包,避免重复加载报错
/// </summary>
private Dictionary<string, AssetBundle> abDic = new Dictionary<string, AssetBundle>();
public static AssetBundleMgr Instance { get; private set; }
protected virtual void Awake() {
if (Instance == null) {
Instance = this;
DontDestroyOnLoad(gameObject);
}
}
/// <summary>
/// 同步加载 AB 包
/// </summary>
/// <param name="abName"></param>
public void LoadAB(string abName) {
// 加载主包
if (mainAB == null) {
mainAB = AssetBundle.LoadFromFile(AB_DIRECTORY + MAIN_AB_NAME);
manifest = mainAB.LoadAsset<AssetBundleManifest>(nameof(AssetBundleManifest));
}
// 获取依赖包相关信息
string[] strs = manifest.GetAllDependencies(abName);
for (int i = 0; i < strs.Length; i++) {
if (!abDic.ContainsKey(strs[i])) {
AssetBundle temp = AssetBundle.LoadFromFile(AB_DIRECTORY + strs[i]);
abDic.Add(strs[i], temp);
}
}
// 加载 AB 包
if (!abDic.ContainsKey(abName)) {
AssetBundle ab = AssetBundle.LoadFromFile(AB_DIRECTORY + abName);
abDic.Add(abName, ab);
}
}
/// <summary>
/// 使用泛型加载 AB 包内的资源
/// </summary>
/// <param name="abName"></param>
/// <param name="resName"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T LoadRes<T>(string abName, string resName) where T : Object {
// 加载 AB 包
LoadAB(abName);
return abDic[abName].LoadAsset(resName) as T;
}
/// <summary>
/// 加载 AB 包内的资源
/// </summary>
/// <param name="abName"></param>
/// <param name="resName"></param>
/// <param name="type"></param>
/// <returns></returns>
public Object LoadRes(string abName, string resName, Type type) {
// 加载 AB 包
LoadAB(abName);
return abDic[abName].LoadAsset(resName, type);
}
/// <summary>
/// 异步加载 AB 包资源(加载 AB 包同步,加载资源异步)
/// </summary>
/// <param name="abName"></param>
/// <param name="resName"></param>
/// <param name="type"></param>
/// <param name="callBack"></param>
public void LoadResAsync(string abName, string resName, Type type, UnityAction<Object> callBack) {
// 启动协程
StartCoroutine(ReallyLoadResAsync(abName, resName, type, callBack));
}
/// <summary>
/// 异步加载协程(加载 AB 包同步,加载资源异步)
/// </summary>
/// <param name="abName"></param>
/// <param name="resName"></param>
/// <param name="type"></param>
/// <param name="callBack"></param>
/// <returns></returns>
private IEnumerator ReallyLoadResAsync(string abName, string resName, Type type, UnityAction<Object> callBack) {
// 加载 AB 包
LoadAB(abName);
// 异步加载资源
AssetBundleRequest abr = abDic[abName].LoadAssetAsync(resName, type);
yield return abr;
// 执行回调委托
callBack(abr.asset);
}
/// <summary>
/// 异步加载 AB 包资源(加载 AB 包同步,加载资源异步)
/// </summary>
/// <param name="abName"></param>
/// <param name="resName"></param>
/// <param name="callBack"></param>
public void LoadResAsync<T>(string abName, string resName, UnityAction<T> callBack) where T : Object {
// 启动协程
StartCoroutine(ReallyLoadResAsync(abName, resName, callBack));
}
/// <summary>
/// 异步加载协程(加载 AB 包同步,加载资源异步)
/// </summary>
/// <param name="abName"></param>
/// <param name="resName"></param>
/// <param name="type"></param>
/// <param name="callBack"></param>
/// <returns></returns>
private IEnumerator ReallyLoadResAsync<T>(string abName, string resName, UnityAction<T> callBack) where T : Object {
// 加载 AB 包
LoadAB(abName);
// 异步加载资源
AssetBundleRequest abr = abDic[abName].LoadAssetAsync<T>(resName);
yield return abr;
// 执行回调委托
callBack(abr.asset as T);
}
/// <summary>
/// 卸载指定 AB 包
/// </summary>
/// <param name="abName"></param>
/// <param name="unloadAllLoadedObjects"></param>
public void UnLoad(string abName, bool unloadAllLoadedObjects = false) {
if (abDic.ContainsKey(abName)) {
abDic[abName].Unload(unloadAllLoadedObjects);
abDic.Remove(abName);
}
}
/// <summary>
/// 卸载所有 AB 包
/// </summary>
/// <param name="unloadAllLoadedObjects"></param>
public void UnLoadAll(bool unloadAllLoadedObjects = false) {
AssetBundle.UnloadAllAssetBundles(unloadAllLoadedObjects);
abDic.Clear();
mainAB = null;
manifest = null;
}
}
2023-06-08 Unity AssetBundle2——AB包资源管理器AssetBundleMgr
最新推荐文章于 2024-08-05 14:41:47 发布
该代码实现了一个用于管理Unity3DAssetBundle的类AssetBundleMgr,它负责同步和异步加载AB包,处理依赖关系,并提供资源的加载和卸载功能。AssetBundleMgr使用静态单例模式,确保游戏运行期间只有一个实例存在。
摘要由CSDN通过智能技术生成