1. 程式人生 > >場景載入進度條的完美方案

場景載入進度條的完美方案

轉自: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.     loadingText.text = "載入場景中...";  
  5.     int startProgress = (int)(startPercent * 100);  
  6.     int displayProgress = startProgress;  
  7.     int toProgress = startProgress;  
  8.     AsyncOperation op = Application.LoadLevelAsync(sceneName);  
  9.     op.allowSceneActivation = false;  
  10.     while (op.progress < 0.9f)  
  11.     {  
  12.         toProgress = startProgress + (int)(op.progress * (1.0f - startPercent) * 100);  
  13.         while (displayProgress < toProgress)  
  14.         {  
  15.             ++displayProgress;  
  16.             SetProgress(displayProgress);  
  17.             yield return null;  
  18.         }  
  19.         yield return null;  
  20.     }  
  21.     toProgress = 100;  
  22.     while (displayProgress < toProgress)  
  23.     {  
  24.         ++displayProgress;  
  25.         SetProgress(displayProgress);  
  26.         yield return null;  
  27.     }  
  28.     op.allowSceneActivation = true;  
  29. }  
  30. IEnumerator LoadBundleScene(string sceneName)  
  31. {  
  32.     string path = BundleManager.GetBundleLoadPath(BundleManager.PathSceneData, sceneName + ".data");  
  33.     WWW www = new WWW(path);  
  34.     loadingText.text = "載入資源包中...";  
  35.     int displayProgress = 0;  
  36.     int toProgress = 0;  
  37.     while (!www.isDone)  
  38.     {  
  39.         toProgress = (int)(www.progress * m_BundlePercent * 100);  
  40.         while (displayProgress < toProgress)  
  41.         {  
  42.             ++displayProgress;  
  43.             SetProgress(displayProgress);  
  44.             yield return null;  
  45.         }  
  46.         yield return null;  
  47.     }  
  48.     toProgress = (int)(m_BundlePercent * 100);  
  49.     while (displayProgress < toProgress)  
  50.     {  
  51.         ++displayProgress;  
  52.         SetProgress(displayProgress);  
  53.         yield return null;  
  54.     }  
  55.     yield return www;  
  56.     if (null != www.assetBundle)  
  57.     {  
  58.         m_LastSceneBundle = www.assetBundle;  
  59.         yield return StartCoroutine(LoadNormalScene(sceneName, m_BundlePercent));  
  60.     }  
  61. }  
  62. void SetProgress(int progress)  
  63. {  
  64.     loadingBar.value = progress * 0.01f;  
  65.     loadingProgress.text = progress.ToString() + " %";  
  66. }  


LoadNoramlScene表示載入沒有打包的場景

LoadBundleScene表示載入打包的場景

m_BundlePercent表示載入bundle包占總進度的百分比,預設0.7f