AB包管理器
让外部更方便的进行资源加载
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class ABMgr : MonoBehaviour
{
//单例模式
public static ABMgr instance;
//将已经加载的AB包存储起来 防止重复加载
private Dictionary<string, AssetBundle> abDic = new Dictionary<string, AssetBundle>();
AssetBundle mainAB;
AssetBundleManifest manifest;
private string Path
{
get {
return Application.streamingAssetsPath + "/";
}
}
private void Awake()
{
if (instance == null)
instance = this;
}
public void LoadAB(string abName)
{
if (mainAB == null)
{
mainAB = AssetBundle.LoadFromFile(Path + abName);
manifest = mainAB.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
}
//获取依赖信息
string[] dirs = manifest.GetAllDependencies(abName);
for (int i = 0; i < dirs.Length; i++)
{
if (!abDic.ContainsKey(dirs[i]))
{
AssetBundle manifestab = AssetBundle.LoadFromFile(Path + dirs[i]);
abDic.Add(dirs[i], manifestab);
}
}
//加载资源主包
if (!abDic.ContainsKey(abName))
{
AssetBundle ab = AssetBundle.LoadFromFile(Path + abName);
abDic.Add(abName, ab);
}
}
#region 同步加载
//同步加载
public Object LoadRes(string abName, string resName)
{
LoadAB(abName);
//为了外面方便 在加载资源时 判断一下 是不是GameObjet
//如果是 直接在内部实例化
Object obj = abDic[abName].LoadAsset(resName);
if (obj is GameObject)
{
return Instantiate(obj);
}
//加载资源
return obj;
}
//重载方法 根据type加载
public Object LoadRes(string abName, string resName, System.Type type)
{
LoadAB(abName);
Object obj = abDic[abName].LoadAsset(resName, type);
if (obj is GameObject)
{
return Instantiate(obj);
}
return obj;
}
//重载方法 根据泛型加载
public T LoadRes<T>(string abName, string resName) where T : Object
{
LoadAB(abName);
T obj = abDic[abName].LoadAsset<T>(resName);
if (obj is GameObject)
{
return Instantiate(obj);
}
return obj;
}
#endregion
#region 异步加载
//根据名字异步加载
public void LoadREsAsync(string abName, string resName, UnityAction<Object> callback)
{
StartCoroutine(RellyLoadAsync(abName, resName, callback));
}
IEnumerator RellyLoadAsync(string abName, string resName, UnityAction<Object> callback)
{
LoadAB(abName);
//为了外面方便 在加载资源时 判断一下 是不是GameObjet
//如果是 直接在内部实例化
AssetBundleRequest abr = abDic[abName].LoadAssetAsync(resName);
yield return abr;
//异步加载结束后 通过委托传递出去
if (abr.asset is GameObject)
{
callback(Instantiate(abr.asset));
}
else
{
callback(abr.asset);
}
}
//根据Type异步加载
public void LoadREsAsync(string abName, string resName, System.Type type, UnityAction<Object> callback)
{
StartCoroutine(RellyLoadAsync(abName, resName, type, callback));
}
IEnumerator RellyLoadAsync(string abName, string resName, System.Type type, UnityAction<Object> callback)
{
LoadAB(abName);
//为了外面方便 在加载资源时 判断一下 是不是GameObjet
//如果是 直接在内部实例化
AssetBundleRequest abr = abDic[abName].LoadAssetAsync(resName, type);
yield return abr;
//异步加载结束后 通过委托传递出去
if (abr.asset is GameObject)
{
callback(Instantiate(abr.asset));
}
else
{
callback(abr.asset);
}
}
//使用泛型异步加载
public void LoadREsAsync<T>(string abName, string resName, UnityAction<T> callback) where T : Object
{
StartCoroutine(RellyLoadAsync<T>(abName, resName, callback));
}
IEnumerator RellyLoadAsync<T>(string abName, string resName, UnityAction<T> callback) where T : Object
{
LoadAB(abName);
AssetBundleRequest abr = abDic[abName].LoadAssetAsync<T>(resName);
yield return abr;
//异步加载结束后 通过委托传递出去
if (abr.asset is GameObject)
{
callback(Instantiate(abr.asset) as T);
}
else
{
callback(abr.asset as T);
}
}
#endregion
#region 卸载
//单个包卸载
public void UnLoad(string abName)
{
if (abDic.ContainsKey(abName))
{
abDic[abName].Unload(false);
abDic.Remove(abName);
}
}
//所有包卸载
public void ClearAB()
{
AssetBundle.UnloadAllAssetBundles(false);
abDic.Clear();
mainAB = null;
manifest = null;
}
#endregion
}