前置知识,了解asset的加载API和asset依赖,以及asset三种加载方式
Singleton<ABManager>是单例模式的父类 可以不继承自己写
根据项目替换 PathUrl 和 MainABName主包名这里安卓IOS电脑默认主包名就是简写
包含同步加载3异步加载3和卸载方法2
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class ABManager : Singleton<ABManager>
{
//AB包管理器的目地:让外部更方便的进行资源加载
//字典管理当前已经加载的包
private Dictionary<string, AssetBundle> LoadBundles = new Dictionary<string, AssetBundle>();
//主包(包含所有包的依赖关系)
private AssetBundle mainAssetBundle = null;
//主包的依赖文件
private AssetBundleManifest assetBundleManifest = null;//固定写法
public string PathUrl { get { return Application.streamingAssetsPath + "/"; } }//方便以后更改包的路径
public string MainABName //主包名也可能改
{
get
{
#if UNITY_IOS
return "IOS";
#elif UNITY_ANDROID
return "ANDROID";
#else
return "PCWindows";
#endif
}
}
//加载包工具方法
public void Load(string ABname)
{
//加载主包和主包依赖关系文件
if (mainAssetBundle == null)
{
mainAssetBundle = AssetBundle.LoadFromFile(PathUrl + MainABName);
assetBundleManifest = mainAssetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");//固定写法
}
//加载主包依赖关系文件的依赖信息
//并加载依赖包
string[] str = assetBundleManifest.GetAllDependencies(ABname);
for (int i = 0; i < str.Length; i++)
{
if (!LoadBundles.ContainsKey(str[i]))
{
var ABTemp = AssetBundle.LoadFromFile(PathUrl + str[i]);
LoadBundles.Add(str[i], ABTemp);
}
}
//加载目标包
if (!LoadBundles.ContainsKey(ABname))
{
var TargetAB = AssetBundle.LoadFromFile(PathUrl + ABname);
LoadBundles.Add(ABname, TargetAB);//加入数组
}
}
//同步加载
#region 按名字加载
public Object ABLoad(string ABname, string Resname) //包名 资源名<加载的资源类型>
{
Load(ABname);
//加载目标资源
//按名字加载
Object @object = LoadBundles[ABname].LoadAsset(Resname);
if (@object is GameObject) return Instantiate(@object);
else return @object;
}
#endregion
#region 按类型加载
public Object ABLoad(string ABname, string Resname, System.Type type) //包名 资源名 加载的种类
{
Load(ABname);
//加载目标资源
//按名字加载
Object @object = LoadBundles[ABname].LoadAsset(Resname, type);
if (@object is GameObject) return Instantiate(@object);
else return @object;
//LoadBundles[ABname].LoadAsset<T>(Resname);
}
#endregion
#region 按泛型加载
public T ABLoad<T>(string ABname, string Resname) where T : Object //包名 资源名<加载的资源类型>
{
Load(ABname);
//加载目标资源
//按名字加载
T @object = LoadBundles[ABname].LoadAsset<T>(Resname);
if (@object is GameObject) return Instantiate(@object);
else return @object;
}
#endregion
//异步加载 只有资源是异步加载的 AB包依然同步加载
#region 根据名字加载
public void ABLoadAsync(string ABname, string Resname, UnityAction<Object> callback)
{
StartCoroutine(ReallyABLoadAsync(ABname, Resname, callback));
}
IEnumerator ReallyABLoadAsync(string ABname, string Resname, UnityAction<Object> callback)
{
Load(ABname);
AssetBundleRequest asset = LoadBundles[ABname].LoadAssetAsync(Resname);
yield return asset;
Object @object = asset.asset;
if (@object is GameObject) callback(Instantiate(@object));
else callback(@object);
}
#endregion
#region 根据Type加载
public void ABLoadAsync(string ABname, string Resname, System.Type type,UnityAction<Object> callback)
{
StartCoroutine(ReallyABLoadAsync(ABname, Resname, type, callback));
}
IEnumerator ReallyABLoadAsync(string ABname, string Resname, System.Type type, UnityAction<Object> callback)
{
Load(ABname);
AssetBundleRequest asset = LoadBundles[ABname].LoadAssetAsync(Resname, type);
yield return asset;
Object @object = asset.asset;
if (@object is GameObject) callback(Instantiate(@object));
else callback(@object);
}
#endregion
#region 根据泛型加载
public void ABLoadAsync<T>(string ABname, string Resname, UnityAction<T> callback)where T:Object
{
StartCoroutine(ReallyABLoadAsync(ABname, Resname, callback));
}
IEnumerator ReallyABLoadAsync<T>(string ABname, string Resname, UnityAction<T> callback) where T : Object
{
Load(ABname);
AssetBundleRequest asset = LoadBundles[ABname].LoadAssetAsync<T>(Resname);
yield return asset;
Object @object = asset.asset;
if (@object is T) callback(Instantiate(@object as T));
else callback(@object as T);
}
#endregion
//单个包的卸载
public void ABUnLoad(string ABname, bool IsRemoveAll = false)
{
if (LoadBundles.ContainsKey(ABname))
{
LoadBundles[ABname].Unload(IsRemoveAll);
LoadBundles.Remove(ABname);
}
}
//所有包的卸载
public void ABUnLoadAll(bool IsRemoveAll = false)
{
AssetBundle.UnloadAllAssetBundles(IsRemoveAll);
LoadBundles.Clear();
mainAssetBundle = null;
assetBundleManifest = null;
}
}