AssetBundle资源管理器
Contents
AbMgr
using System.Collections;
using System.Collections.Generic;
using ProjectBase.Mono;
using ProjectBase.SingleBase;
using UnityEngine;
using UnityEngine.Events;
namespace ProjectBase.Res
{
/// <summary>
/// AB包资源加载
/// </summary>
public class AbMgr : Single<AbMgr>
{
/// <summary>
/// AB包字典
/// </summary>
Dictionary<string, AssetBundle> mAbDict = new Dictionary<string, AssetBundle>();
/// <summary>
/// AB包主包
/// </summary>
private AssetBundle mMainAb;
/// <summary>
/// 主包AssetBundleManifest对象
/// </summary>
private AssetBundleManifest mMainAbm;
/// <summary>
/// AB包的存放路径
/// </summary>
private string mPathUrl => Application.streamingAssetsPath + "/";
/// <summary>
/// 主包路径
/// </summary>
private string mMainUrl
{
get
{
#if UNITY_IOS
return "IOS"+"/";
#elif UNITY_EDITOR_OSX
return "StandaloneOSXUniversal";
#else
return "PC"+"/";
#endif
}
}
/// <summary>
/// 同步加载AB包
/// </summary>
/// <param name="abName"></param>
/// <returns></returns>
private AssetBundle Load(string abName)
{
LoadRely(abName);
if (!mAbDict.ContainsKey(abName))
{
mAbDict.Add(abName, AssetBundle.LoadFromFile(mPathUrl + abName));
}
return mAbDict[abName];
}
/// <summary>
/// 同步加载AB包依赖
/// </summary>
/// <param name="abName"></param>
private void LoadRely(string abName)
{
if (mMainAb == null)
{
mMainAb = AssetBundle.LoadFromFile(mPathUrl + mMainUrl);
mMainAbm = mMainAb.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
}
string[] names = mMainAbm.GetAllDependencies(abName);
foreach (var value in names)
{
if (mAbDict.ContainsKey(value)) continue; //如果已经加载了 就不再加载
mAbDict.Add(value, AssetBundle.LoadFromFile(mPathUrl + value));
}
}
/// <summary>
/// 异步加载AB包
/// </summary>
/// <param name="abName"></param>
/// <param name="callBack"></param>
private void LoadAsync(string abName, UnityAction<AssetBundle> callBack)
{
MonoManager.Instance.StartCoroutine(IELoadAsync(abName, callBack));
}
/// <summary>
/// 异步加载AB包协程
/// </summary>
/// <param name="abName"></param>
/// <param name="callBack"></param>
/// <returns></returns>
private IEnumerator IELoadAsync(string abName, UnityAction<AssetBundle> callBack)
{
Coroutine coroutine = MonoManager.Instance.StartCoroutine(IELoadRelyAsync(abName));
yield return coroutine;
if (!mAbDict.ContainsKey(abName))
{
AssetBundleCreateRequest abcq = AssetBundle.LoadFromFileAsync(mPathUrl + abName);
yield return abcq;
if (abcq.assetBundle == null) yield break;
mAbDict.Add(abName, abcq.assetBundle);
callBack.Invoke(abcq.assetBundle);
yield break;
}
callBack.Invoke(mAbDict[abName]);
}
/// <summary>
/// 异步加载AB包依赖携程
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
private IEnumerator IELoadRelyAsync(string abName)
{
//异步加载主包
if (mMainAb == null)
{
var abcq = AssetBundle.LoadFromFileAsync(mPathUrl + mMainUrl);
yield return abcq;
mMainAb = abcq.assetBundle;
var assetBundleRequest = abcq.assetBundle.LoadAssetAsync<AssetBundleManifest>("AssetBundleManifest");
yield return assetBundleRequest;
mMainAbm = assetBundleRequest.asset as AssetBundleManifest;
}
string[] names = mMainAbm.GetAllDependencies(abName);
foreach (var value in names)
{
if (mAbDict.ContainsKey(value)) continue; //如果已经加载了 就不再加载
var request = AssetBundle.LoadFromFileAsync(mPathUrl + value);
yield return request;
mAbDict.Add(value, request.assetBundle);
}
}
/// <summary>
/// 同步加载AB包中的资源
/// </summary>
/// <param name="abName"></param>
/// <param name="resName"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T LoadAsset<T>(string abName, string resName) where T : Object
{
return !mAbDict.ContainsKey(abName) ? Load(abName).LoadAsset<T>(resName) : mAbDict[abName].LoadAsset<T>(resName);
}
/// <summary>
/// 异步加载AB包中的资源
/// </summary>
/// <param name="abName"></param>
/// <param name="resName"></param>
/// <param name="callBack"></param>
/// <typeparam name="T"></typeparam>
public void LoadAssetAsync<T>(string abName, string resName, UnityAction<T> callBack) where T : Object
{
if (!mAbDict.ContainsKey(abName))
{
LoadAsync(abName,
(ab) => { MonoManager.Instance.StartCoroutine(IELoadAssetAsync(ab, resName, callBack)); });
}
else
{
MonoManager.Instance.StartCoroutine(IELoadAssetAsync(mAbDict[abName], resName, callBack));
}
}
/// <summary>
/// 异步加载AB包中的资源协程
/// </summary>
/// <param name="assetBundle"></param>
/// <param name="resName"></param>
/// <param name="callBack"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
private IEnumerator IELoadAssetAsync<T>(AssetBundle assetBundle, string resName, UnityAction<T> callBack)
where T : Object
{
var abq = assetBundle.LoadAssetAsync<T>(resName);
yield return abq;
if (abq.asset == null) yield break;
callBack.Invoke(abq.asset as T);
}
/// <summary>
/// 卸载AB包
/// </summary>
/// <param name="name"></param>
/// <param name="unloadObjects"></param>
public void UnLoad(string name, bool unloadObjects = false)
{
if (!mAbDict.ContainsKey(name)) return;
mAbDict[name].Unload(unloadObjects);
mAbDict.Remove(name);
}
/// <summary>
/// 卸载所有ab包
/// </summary>
public void UnLoadAll(bool unloadObjects = false)
{
AssetBundle.UnloadAllAssetBundles(unloadObjects);
mAbDict.Clear();
}
}
}测试
//同步加载
Instantiate(AbMgr.Instance.LoadAsset<GameObject>("cube", "cube2"));
//异步加载
AbMgr.Instance.LoadAssetAsync<GameObject>("cube", "cube2", (obj =>
{
Instantiate(obj);
}));