场景加载进度条的完美方案

转自:http://www.cnblogs.com/czaoth/p/5785630.html

我以为做个进度条很简单,分分钟解决,结果折腾了一天才搞定,Unity有很多坑,要做完美需要逐一解决.

问题1:最简单的方法不能实现100%的进度

用最简单的方法来实现,不能实现100%的进度,原因是Unity加载完新场景立马就激活新场景了,无法显示最后的进度.解决办法就是使用allowSceneActivation来控制进入场景的时机.

问题2:使用allowSceneActivation后进度卡在90%

这个问题官网论坛也有人讨论,解决办法就是自己手动修补最后的10%,

问题3:进度条一顿一顿地增加.不平滑

解决办法手动插值平滑

问题4:www和LoadLevelAsync两部分进度的整合问题

大部分场景是打成Bundle包的,先要WWW加载,再LoadLevelAsync,两部分的进度要整合在一起,

少量场景是不打Bundle包的,比如登录场景,

 

  1. if (nextSceneID == (int)GlobeEnum.SceneDefine.LOGIN)  
  2.     yield return StartCoroutine(LoadNormalScene(sceneTable.ResName));  
  3. else  
  4.     yield return StartCoroutine(LoadBundleScene(sceneTable.ResName));  

 

 

问题5:用yield return null代替Update()来处理每帧的进度界面更新.

用yield return null来处理更新,比如在Update函数里面处理,代码更简洁,但是要注意一个问题就是while死循环的问题

每个while的地方必须要对应一个yield return null,

 

经过以上处理,进度条看起来完美了很多,终于能满足我这个完美主义者的要求了. (o_o)

 

代码如下:

 

  1. IEnumerator LoadNormalScene(string sceneName, float startPercent = 0)  
  2. {  
  3.     GameRoot.Instance.CurrentSceneId = (int)LoadingWindow.nextSceneID;  
  4.   
  5.     loadingText.text = "加载场景中...";  
  6.   
  7.     int startProgress = (int)(startPercent * 100);  
  8.     int displayProgress = startProgress;  
  9.     int toProgress = startProgress;  
  10.     AsyncOperation op = Application.LoadLevelAsync(sceneName);  
  11.     op.allowSceneActivation = false;  
  12.     while (op.progress < 0.9f)  
  13.     {  
  14.         toProgress = startProgress + (int)(op.progress * (1.0f - startPercent) * 100);  
  15.         while (displayProgress < toProgress)  
  16.         {  
  17.             ++displayProgress;  
  18.             SetProgress(displayProgress);  
  19.             yield return null;  
  20.         }  
  21.         yield return null;  
  22.     }  
  23.   
  24.     toProgress = 100;  
  25.     while (displayProgress < toProgress)  
  26.     {  
  27.         ++displayProgress;  
  28.         SetProgress(displayProgress);  
  29.         yield return null;  
  30.     }  
  31.     op.allowSceneActivation = true;  
  32. }  
  33.   
  34. IEnumerator LoadBundleScene(string sceneName)  
  35. {  
  36.     string path = BundleManager.GetBundleLoadPath(BundleManager.PathSceneData, sceneName + ".data");  
  37.     WWW www = new WWW(path);  
  38.   
  39.     loadingText.text = "加载资源包中...";  
  40.     int displayProgress = 0;  
  41.     int toProgress = 0;  
  42.     while (!www.isDone)  
  43.     {  
  44.         toProgress = (int)(www.progress * m_BundlePercent * 100);  
  45.         while (displayProgress < toProgress)  
  46.         {  
  47.             ++displayProgress;  
  48.             SetProgress(displayProgress);  
  49.             yield return null;  
  50.         }  
  51.         yield return null;  
  52.     }  
  53.   
  54.     toProgress = (int)(m_BundlePercent * 100);  
  55.     while (displayProgress < toProgress)  
  56.     {  
  57.         ++displayProgress;  
  58.         SetProgress(displayProgress);  
  59.         yield return null;  
  60.     }  
  61.   
  62.     yield return www;  
  63.     if (null != www.assetBundle)  
  64.     {  
  65.         m_LastSceneBundle = www.assetBundle;  
  66.         yield return StartCoroutine(LoadNormalScene(sceneName, m_BundlePercent));  
  67.     }  
  68. }  
  69.   
  70. void SetProgress(int progress)  
  71. {  
  72.     loadingBar.value = progress * 0.01f;  
  73.     loadingProgress.text = progress.ToString() + " %";  
  74. }  


LoadNoramlScene表示加载没有打包的场景

 

LoadBundleScene表示加载打包的场景

m_BundlePercent表示加载bundle包占总进度的百分比,默认0.7f


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值