I use AssetBundle to download bundle from our server. Each time we start the game, we call _DownloadBundle() to check if bundle is downloaded or not, if it is downloaded, there is a error message
at line "bundle = www.assetBundle;"> The AssetBundle>.......................................... can't be loaded because another> AssetBundle with the same files is> already loaded.> UnityEngine.WWW:get_assetBundle()><_DownloadBundle>c__Iterator3:MoveNext()> (at> Assets/ProjectFiles/Scripts/Game/Models/StoryScreen/BundleManager.cs:1179)> UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator,> IntPtr)
but the game can be run normally and we can catch that error message through the OnError method below in old Unity (v5.2.5f1), but after update to Unity v2017, the game stuck at the that error message and I cannot catch the error message to bypass it.
This is my download bundle method:
private IEnumerator _DownloadBundle (string packname, bool load, bool waitforinit, float sleep, int index, int total, UnityEngine.ThreadPriority priority = UnityEngine.ThreadPriority.Normal)
{
EventHandler onprogress = BundleManager.OnProgress;
if (waitforinit) {
while (!BundleManager.IsLoaded) {
if (onprogress != null) {
onprogress (null, new EventProgressArg (packname, 0, 0, 0, 0, false, 0, false, null));
}
yield return null;
}
}
float overall = (float)index / total;
float overallstep = (float)1 / total;
bool error = false;
string errormessage = null;
int version = BundleManager.GetPackVersion (packname);
long size = BundleManager.GetPackSize (packname);
string url = BundleManager.GetPackUrl (packname, version);
if (url == null) {
Utils.Log(string.Format ("Invalid URL for bundle: '{0}', version '{1}'!", packname, version));
yield break;
}
DateTime begin = DateTime.Now;
Utils.Log(string.Format ("Download bundle '{0}', version '{1}' from '{2}'", packname, version, url));
WWW www = null;
bool loadcached = true;
try {
www = WWW.LoadFromCacheOrDownload (url, version);
www.threadPriority = priority;
} catch (Exception e) {
Utils.Log(string.Format ("Failed to download bundle '{0}', version '{1}'\n Error: {2}", packname, version, e.Message));
yield break;
}
float progress = 0;
while (!www.isDone) {
loadcached = false;
if (onprogress != null) {
progress = www.progress;
onprogress (null, new EventProgressArg (packname, overall + progress * overallstep, progress, index, total, loadcached, size, false, null));
}
yield return null;
}
if (www.isDone && string.IsNullOrEmpty (www.error)) {
AssetBundle bundle = null;
try {
bundle = www.assetBundle;
if (bundle != null) {
if (load) {
BundleManager.Bundles.Add (packname, bundle);
Utils.Log(string.Format ("Bundle '{0}', version '{1}' downloaded & loaded in '{2}' seconds.", packname, version, DateTime.Now - begin));
} else {
bundle.Unload (true);
Utils.Log(string.Format ("Bundle '{0}', version '{1}' downloaded in '{2}' seconds.", packname, version, DateTime.Now - begin));
}
error = false;
} else {
error = true;
Utils.Log(string.Format ("Failed to load bundle '{0}', version '{1}'.", packname, version));
}
} catch (Exception e) {
error = true;
errormessage = e.Message;
Utils.Log(string.Format ("Failed to load bundle '{0}', version '{1}'\n Error: '{2}'", packname, version, e.Message));
}
} else {
error = true;
errormessage = www.error;
Utils.Log(string.Format ("Failed to download bundle '{0}', version '{1}'\n Error: '{2}'", packname, version, www.error));
}
BundleManager.LastError = error;
if (error) {
EventHandler onerror = BundleManager.OnError;
if (onerror != null) {
yield return null;
onerror (null, new EventProgressArg (packname, overall, progress, index, total, loadcached, size, error, errormessage));
}
}
EventHandler onbundlecomplete = BundleManager.OnBundleComplete;
if (onbundlecomplete != null) {
yield return null;
onbundlecomplete (null, new EventProgressArg (packname, overall, 1, index, total, loadcached, size, error, errormessage));
}
}
And this is the method I used to catch the Error message in old Unity version:
BundleManager.OnError = null;
BundleManager.OnError += (sender, e) => {
EventProgressArg progress = e as EventProgressArg;
if (Director.Instance.IsSplashScreen ()) {
if (!(progress.ErrorMessage.Contains("A file of the same name is already loaded from another AssetBundle")
|| progress.ErrorMessage.Contains("loaded because another AssetBundle with the same files is already loaded"))) {
#if UNITY_IPHONE
if (Application.platform == RuntimePlatform.IPhonePlayer) {
CustomAlertManager.alertButtonClickedEvent += (button) => {
Application.Quit ();
};
string[] buttons = new string[] { "Exit" };
IosAlert.showAlertWithTitle ("Error", "Download failed. Please check your internet connection and try again.", buttons);
}
#endif
#if UNITY_ANDROID
if (Application.platform == RuntimePlatform.Android) {
CustomAlertManager.alertButtonClickedEvent += (button) => {
Application.Quit ();
};
MyAndroidPlugins.ShowAlert ("Error", "Download failed. Please check your internet connection and try again.", "Exit");
}
#endif
#if UNITY_EDITOR
Utils.Log("Download failed. Please check your internet connection and try again.");
#endif
}
}
};
I have some ideal but don't know how to do it
1. Get the error message and bypass this message (but I don't know how to get that, EventProgressArg.ErrorMessage and www.error does not work now)
2. Check if bundle is loaded or not before set bundle = www.assetBundle (but I don't know how to check it)
Anyone have any ideal for my situation ?
Thank everyone.
↧