这里提供一个简单的ab加载管理器
using System.Collections;
using System.Collections.Generic;using UnityEngine;
using UnityEngine.SceneManagement;
public class LoadAssetBundleManager : MonoBehaviour {
#region 声明变量
#region 单例
private static LoadAssetBundleManager instance;
public static LoadAssetBundleManager Instance
{
get
{
if (instance == null)
{
instance = new GameObject("LoadAssetBundleManager").AddComponent<LoadAssetBundleManager>();
}
return instance;
}
}
#endregion
#region 加载
//AssetBundleManifest 总体的AssetBundleManifest
AssetBundleManifest mainAssetBundleManifest;
//下载路径
string URL;
//AssetBundleManifest 名字
public string assetBundleManifestName = "";
//下载完后的委托
public delegate void HandleFinishDownload(WWW www);
//加载完后的委托
public delegate void HandleFinishInstantiate(Object go);
#endregion
#region 卸载
Dictionary<string, LoadedAssetBundle> loadedAssetBundles;
Dictionary<string, string[]> dependencies;
#endregion
#endregion
#region 提供外部方法
/// <summary>
/// 加载所需要的AssetBundle
/// </summary>
/// <param name="assetBundleName"></param>
/// <param name="instantiateFun"></param>
/// <returns></returns>
public IEnumerator LoadAssetBundle(string assetBundleName, HandleFinishInstantiate instantiateFun, bool isLoadScene = false)
{
AssetBundle assetBundle = null;
assetBundle = LoadAssetBundleInternal(assetBundleName);
if (assetBundle == null)
{
Debug.LogError("新加载____" + assetBundleName);
//获取依赖文件列表
string[] dependentAssetBundles = mainAssetBundleManifest.GetAllDependencies(assetBundleName);
AddDependencies(assetBundleName, dependentAssetBundles);
AssetBundle[] abs = new AssetBundle[dependentAssetBundles.Length];
for (int i = 0; i < dependentAssetBundles.Length; i++)
{
//加载所有的依赖文件
WWW www = new WWW(URL + dependentAssetBundles[i]);
yield return www;
abs[i] = www.assetBundle;
AddLoadedAssetBundles(dependentAssetBundles[i], new LoadedAssetBundle(abs[i]));
}
//加载需要的文件
WWW loadAssetBundle = new WWW(URL + assetBundleName);
yield return loadAssetBundle;
assetBundle = loadAssetBundle.assetBundle;
AddLoadedAssetBundles(assetBundleName, new LoadedAssetBundle(assetBundle));
}
else
{
Debug.LogError("已经加载过了____" + assetBundleName);
}
if (isLoadScene)
{
//加载场景(使用场景名称)
SceneManager.LoadScene(assetBundleName);
}
else
{
if (instantiateFun != null)
instantiateFun(assetBundle.LoadAsset(assetBundleName));
}
//UnloadAssetBundle(assetBundleName);
}
/// <summary>
/// 卸载目标AssetBundle
/// </summary>
/// <param name="assetBundleName"></param>
/// <param name="unLoad"></param>
public void UnloadAssetBundle(string assetBundleName, bool unLoad = false)
{
Debug.LogError("卸载____"+ assetBundleName);
UnloadAssetBundleInternal(assetBundleName, unLoad);
UnloadDependencies(assetBundleName, unLoad);
}
#endregion
#region 内部方法实现
void Awake()
{
instance = this;
Initialize();
}
/// <summary>
/// 初始化数据
/// </summary>
void Initialize()
{
//暂时只定义一种
URL = "file://" + Application.streamingAssetsPath + "/";
assetBundleManifestName = "StreamingAssets";
LoadMainAssetBundleManifest();
loadedAssetBundles = new Dictionary<string, LoadedAssetBundle>();
dependencies = new Dictionary<string, string[]>();
}
/// <summary>
/// 加载总体的AssetBundleManifest
/// </summary>
void LoadMainAssetBundleManifest()
{
StartCoroutine(DownLoad(URL + assetBundleManifestName, delegate (WWW www)
{
AssetBundle manifestBundle = www.assetBundle;
mainAssetBundleManifest = (AssetBundleManifest)manifestBundle.LoadAsset("AssetBundleManifest");
manifestBundle.Unload(false);
}
));
}
/// <summary>
/// 下载WWW
/// </summary>
/// <param name="url"></param>
/// <param name="finishFun"></param>
/// <returns></returns>
private IEnumerator DownLoad(string url, HandleFinishDownload finishFun)
{
WWW www = new WWW(url);
yield return www;
if (www.error != null) Debug.LogError(www.error + "/" + url);
if (finishFun != null)
finishFun(www);
www.Dispose();
}
/// <summary>
/// dependencies 增
/// </summary>
/// <param name="mKey"></param>
/// <param name="mValue"></param>
private void AddDependencies(string mKey, string[] mValue)
{
dependencies.Add(mKey, mValue);
}
/// <summary>
/// dependencies 删
/// </summary>
/// <param name="mKey"></param>
private void UnloadDependencies(string mKey, bool unLoad = false)
{
string[] mDependencies = null;
if (!dependencies.TryGetValue(mKey, out mDependencies)) return;
foreach (var dependency in mDependencies)
{
UnloadAssetBundleInternal(dependency, unLoad);
}
dependencies.Remove(mKey);
}
/// <summary>
/// loadedAssetBundles 增
/// </summary>
/// <param name="mKey"></param>
/// <param name="mValue"></param>
private void AddLoadedAssetBundles(string mKey, LoadedAssetBundle mValue)
{
loadedAssetBundles.Add(mKey, mValue);
}
/// <summary>
/// 从内部加载AssetBundle
/// </summary>
/// <param name="assetBundleName"></param>
/// <returns></returns>
private AssetBundle LoadAssetBundleInternal(string assetBundleName)
{
LoadedAssetBundle bundle = null;
loadedAssetBundles.TryGetValue(assetBundleName, out bundle);
if (bundle != null)
{
bundle.referencedCount++;
return bundle.assetBundle;
}
return null;
}
/// <summary>
/// 从内部卸载AssetBundle
/// </summary>
/// <param name="assetBundleName"></param>
private void UnloadAssetBundleInternal(string assetBundleName, bool unLoad = false)
{
LoadedAssetBundle bundle = GetLoadedAssetBundle(assetBundleName);
if (bundle == null)
return;
if (--bundle.referencedCount == 0)
{
bundle.assetBundle.Unload(unLoad);
loadedAssetBundles.Remove(assetBundleName);
}
}
/// <summary>
/// 获取加载过的AssetBundle
/// </summary>
/// <param name="assetBundleName"></param>
/// <returns></returns>
private LoadedAssetBundle GetLoadedAssetBundle(string assetBundleName)
{
LoadedAssetBundle bundle = null;
loadedAssetBundles.TryGetValue(assetBundleName, out bundle);
if (bundle == null)
return null;
string[] mDependencies = null;
if (!dependencies.TryGetValue(assetBundleName, out mDependencies))
return bundle;
foreach (var dependency in mDependencies)
{
LoadedAssetBundle dependentBundle;
loadedAssetBundles.TryGetValue(dependency, out dependentBundle);
if (dependentBundle == null)
return null;
}
return bundle;
}
#endregion
#region 测试
public string assetBundleName;
public string changeMatName;
void OnGUI()
{
if (GUILayout.Button("Load Cube"))
{
StartCoroutine(LoadAssetBundle(assetBundleName, delegate (Object go)
{
GameObject obj = Instantiate(go) as GameObject;
obj.transform.position = new Vector3(Random.Range(0, 5), 0, Random.Range(0, 5));
}));
}
if (GUILayout.Button("UnLoad Cube"))
{
UnloadAssetBundle(assetBundleName);
}
if (GUILayout.Button("UnLoad Cube True"))
{
UnloadAssetBundle(assetBundleName, true);
}
if (GUILayout.Button("ChangeMat"))
{
StartCoroutine(LoadAssetBundle(changeMatName, delegate (Object go)
{
GameObject obj = GameObject.Find("TestCube(Clone)");
obj.GetComponent<MeshRenderer>().material = go as Material;
}));
}
}
#endregion
}
public class LoadedAssetBundle
{
public AssetBundle assetBundle;
public int referencedCount;
public LoadedAssetBundle(AssetBundle ab)
{
assetBundle = ab;
referencedCount = 1;
}
}