此问题已解决、
加载逻辑有问题,WWW 的并发太高导致通讯堵塞造成的、 修改加载逻辑,保证WWW的低并发就ok了
环境描述
因热更需求,项目4.x升级 5.x
Unity5.6 + windows
AssetBundle打包方式:
1、命名AssetBundleName:文件路径+文件名称+ .myBundle 后缀
Example: assets/resources/gui/tracktaskui.prefab.mybundle (总共有一万+ 个文件)
使用Unity5.x 最新打包函数
[MenuItem("Assetbundle/3_ExportBundle")]
static void ExportBundle() {
EditorUtility.DisplayCancelableProgressBar("ExportBundle", "", 0.5f);
// Choose the output path according to the build target.
string outputPath = Path.Combine("MyAssetBundles", GetPlatformName());
if (!Directory.Exists(outputPath))
Directory.CreateDirectory(outputPath);
//@TODO: use append hash... (Make sure pipeline works correctly with it.)
BuildPipeline.BuildAssetBundles(outputPath, BuildAssetBundleOptions.None, EditorUserBuildSettings.activeBuildTarget);
}
打包出来的资源路劲
file://F:/ThreeKingdom_5_6/ThreeKingdom185_temp1/Assets/../MyAssetBundles/Android/assets/resources/gui/tracktaskui.prefab.mybundle
首先、我会加载 Android(AssetBundle)
然后把依赖描述文件(Android.manifest)读取出来
private AssetBundle main_manifestBundle;
private AssetBundleManifest main_manifest;
public void Init() {
// 1.加载main_Manifest文件
path = GetBundlePath("Android");
if (File.Exists(path))
main_manifestBundle = AssetBundle.LoadFromFile(path);
else
Debug.LogError("file not found:" + path);
main_manifest = (AssetBundleManifest)main_manifestBundle.LoadAsset("AssetBundleManifest");
}
然后就是读取资源了 用www 从本地读取:
在原有框架上 直接改
LoadAsset、LoadUIAsset俩个函数,同时在项目配置中增加个bool 这样就不会干扰到原有逻辑 UseMyAssetBundle=true
public void LoadAsset(string prefab, Action<Object> loaded, Action<float> progress) {
if (SystemSwitch.UseMyAssetBundle) {
StartCoroutine(LoadMyAssetBundle(prefab, loaded, progress,"LoadAsset"));
} else {
var path = m_filesDic.Get(prefab);
//LoggerHelper.Debug(path);
LoadAssets(path, m_queue, ResourceManager.LoadResource, loaded, (resource) => {
if (progress != null && resource != null)
StartCoroutine(ShowProgress(resource, progress));
});
//StartCoroutine(WaitAndDo(path, loaded));
}
}
public void LoadUIAsset(string prefab, Action<Object> loaded, Action<float> progress)
{
if (SystemSwitch.UseMyAssetBundle) {
Debug.Log("LoadUIAsset " + prefab);
StartCoroutine(LoadMyAssetBundle(prefab, loaded, progress, "LoadUIAsset"));
} else {
var path = m_filesDic.Get(prefab);
DebugFilesDicPatp(path, prefab);
//LoggerHelper.Debug(path);
LoadAssets(path, m_queue, ResourceManager.LoadUIResource, loaded, (resource) => {
if (progress != null && resource != null)
StartCoroutine(ShowProgress(resource, progress));
});
//StartCoroutine(WaitAndDo(path, loaded));
}
}
private Dictionary<string, WWW> loadingDic = new Dictionary<string, WWW>();
private IEnumerator LoadMyAssetBundle(string prefab, Action<Object> loaded, Action<float> progress,string loadType) {
prefab = prefab.ToLower();
AssetBundle bundle = new AssetBundle();
string pathTemp = string.Empty;
string prefabTemp = string.Empty;
if (prefab.Contains(".mp3"))
prefabTemp = "mp3";
else if (prefab.Contains(".unity")) {
if (loaded != null)
loaded(null);
} else
prefabTemp = prefab;
Debug.LogError("wwCount: "+loadingDic.Count);
if (MogoWorld.myAssetsManager.MyAssetBundlePathDic.TryGetValue(prefabTemp, out pathTemp)) {
if (MogoWorld.myAssetsManager.AlreadyLoadAssetBundle.TryGetValue(pathTemp, out bundle)) {
if (loaded != null)
loaded(bundle.LoadAsset(prefab));
} else {
string url = SystemConfig.MyAssetBundlePath + pathTemp;
Debug.Log(url);
WWW ww;
if (loadingDic.ContainsKey(pathTemp)) {
ww = loadingDic[pathTemp];
} else {
ww = new WWW(url);
loadingDic.Add(pathTemp, ww);
}
yield return ww;
if (ww.isDone) {
loadingDic.Remove(pathTemp);
if (MogoWorld.myAssetsManager.AlreadyLoadAssetBundle.ContainsKey(pathTemp)) {
LoadAsset(prefab, loaded, progress);
} else {
bundle = ww.assetBundle;
MogoWorld.myAssetsManager.AlreadyLoadAssetBundle.Add(pathTemp, bundle);
string[] depends = MogoWorld.myAssetsManager.MainAssetBundleManifest.GetAllDependencies(pathTemp);
ww.Dispose();
StartCoroutine(LoadMyAssetBundleDepends(prefab, loaded, progress, depends, 0, loadType));
}
}
}
}
}
private IEnumerator LoadMyAssetBundleDepends(string prefab, Action<Object> loaded, Action<float> progress, string[] depends, int curStep, string loadType) {
if (curStep < depends.Length) {
AssetBundle bundle = new AssetBundle();
string path = string.Empty;
path = depends[curStep];
if (MogoWorld.myAssetsManager.AlreadyLoadAssetBundle.TryGetValue(path, out bundle)) {
curStep++;
StartCoroutine(LoadMyAssetBundleDepends(prefab, loaded, progress, depends, curStep, loadType));
} else {
if (loadingDic.ContainsKey(depends[curStep])) {
curStep++;
StartCoroutine(LoadMyAssetBundleDepends(prefab, loaded, progress, depends, curStep, loadType));
} else {
WWW ww = new WWW(SystemConfig.MyAssetBundlePath + path);
yield return ww;
if (ww.isDone) {
bundle = ww.assetBundle;
MogoWorld.myAssetsManager.AlreadyLoadAssetBundle.Add(path, bundle);
curStep++;
StartCoroutine(LoadMyAssetBundleDepends(prefab, loaded, progress, depends, curStep, loadType));
}
}
}
} else {
if (loadType == "LoadAsset") {
LoadAsset(prefab, loaded, progress);
} else if (loadType == "LoadUIAsset") {
LoadUIAsset(prefab, loaded, progress);
}
}
}
LoadAsset 与LoadUIAsset 这俩个函数 为原系统加载AssetBundle的方法、 我下面贴一个调用的例子
这个是调用LoginUI.prefab 的例子
public void ShowMogoLoginUI(Action callback, Action<float> progress = null)
{
if (!UICanChange)
return;
//if (CurrentUI)
// CurrentUI.SetActive(false);
//CurrentUI = m_LoginUI;
//CurrentUI.SetActive(true);
//if (MogoMainCamera.instance)
// MogoMainCamera.instance.SetActive(false);
//m_camUI.clearFlags = CameraClearFlags.Depth;
//ShowBillboardList(false);
if (m_LoginUI == null)
{
if (!IsLoginUILoaded)
{
IsLoginUILoaded = true;
//CallWhenUILoad(0,false);
AssetCacheMgr.GetUIInstance("LoginUI.prefab",//LoginUI
(prefab, guid, go) =>
{
m_LoginUI = go as GameObject;
m_LoginUI.transform.parent = GameObject.Find("MogoMainUIPanel").transform;
m_LoginUI.transform.localPosition = new Vector3(1.25f, -52f, 0);
m_LoginUI.transform.localScale = new Vector3(1, 1, 1);
m_LoginUI.AddComponent<LoginUIViewManager>();
if (CurrentUI != m_LoginUI)
{
if (CurrentUI != null)
{
ShowCurrentUI(false);
}
CurrentUI = m_LoginUI;
ShowCurrentUI(true);
m_camUI.clearFlags = CameraClearFlags.Depth;
//if (MogoMainCamera.instance)
// MogoMainCamera.instance.SetActive(false);
ShowBillboardList(false);
if (callback != null)
{
callback();
}
//MogoGlobleUIManager.Instance.ShowWaitingTip(false);
}
}, progress);
}
}
else
{
if (CurrentUI != m_LoginUI)
{
ShowCurrentUI(false);
CurrentUI = m_LoginUI;
ShowCurrentUI(true);
m_camUI.clearFlags = CameraClearFlags.Depth;
ShowBillboardList(false);
//if (MogoMainCamera.instance)
// MogoMainCamera.instance.SetActive(false);
if (callback != null)
{
callback();
}
}
}
}
那么现在问题出在 协程递归的地方