一般遊戲的主場景包含的資源較多,這會致使加載場景的時間較長。爲了不這個問題,能夠首先加載Loading場景,而後再經過Loading場景來加載主場景。由於Loading場景包含的資源較少,因此加載速度快。在加載主場景的時候通常會在Loading界面中顯示一個進度條來告知玩家當前加載的進度。在Unity中能夠經過調用Application.LoadLevelAsync
函數來異步加載遊戲場景,經過查詢AsyncOperation.progress
的值來獲得場景加載的進度。html
第一步當加載完Loading場景後,調用以下的LoadGame
函數開始加載遊戲場景,使用異步加載的方式加載場景1(Loading場景爲0,主場景爲1),經過Unity提供的Coroutine機制,咱們能夠方便的在每一幀結束後調用SetLoadingPercentage
函數來更新界面中顯示的進度條的數值。網絡
public void LoadGame() { StartCoroutine(StartLoading_1(1)); } private IEnumerator StartLoading_1(int scene) { AsyncOperation op = Application.LoadLevelAsync(scene); while(!op.isDone) { SetLoadingPercentage(op.progress * 100); yield return new WaitForEndOfFrame(); } }
最後進度條的效果顯示以下:異步
進度條並無連續的顯示加載的進度,而是停頓一下切換一個數字,再停頓一下切換一個數子,最後在沒有顯示100%就狀況下就切換到主場景了。究其緣由在於Application.LoadLevelAsync
並非真正的後臺加載,它在每一幀加載一些遊戲資源,並給出一個progress值,因此在加載的時候仍是會形成遊戲卡頓,AsyncOperation.progress
的值也不夠精確。當主場景加載完畢後Unity就自動切換場景,因此上述代碼中的while循環體內的代碼是不會被調用的,致使進度條不會顯示100%。函數
爲了讓進度條能顯示100%,取巧一點的辦法是將AsyncOperation.progress
的值乘上2,這樣當加載到50%的時候界面上就顯示100%了。缺點是當界面上顯示100%的時候,用戶還要等待一段時間纔會進入遊戲。其實Unity提供了手動切換場景的方法,把AsyncOperation.allowSceneActivation
設爲false
就能夠禁止Unity加載完畢後自動切換場景,修改後的StartLoading_2
代碼以下:動畫
// this function is not work private IEnumerator StartLoading_2(int scene) { AsyncOperation op = Application.LoadLevelAsync(scene); op.allowSceneActivation = false; while(!op.isDone) { SetLoadingPercentage(op.progress * 100); yield return new WaitForEndOfFrame(); } op.allowSceneActivation = true; }
咱們首先將AsyncOperation.allowSceneActivation
設爲false
,當加載完成後再設爲true
。代碼看上去沒有錯,可是執行的結果是進度條最後會一直停留在90%上,場景不會切換。經過打印log發現AsyncOperation.isDone
一直爲false
,AsyncOperation.progress
的值增長到0.9後就保持不變了,也就是說場景永遠不會被加載完畢。this
在這個帖子中找到了答案,原來把allowSceneActivation
設置爲false
後,Unity就只會加載場景到90%,剩下的10%要等到allowSceneActivation
設置爲true
後才加載,這不得不說是一個坑。因此代碼改成以下。當AsyncOperation.progress
到達0.9後,就直接把進度條的數值更新爲100%,而後設置AsyncOperation.allowSceneActivation
爲ture
,讓Unity繼續加載未完成的場景。spa
private IEnumerator StartLoading_3(int scene) { AsyncOperation op = Application.LoadLevelAsync(scene); op.allowSceneActivation = false; while(op.progress < 0.9f) { SetLoadingPercentage(op.progress * 100); yield return new WaitForEndOfFrame(); } SetLoadingPercentage(100); yield return new WaitForEndOfFrame(); op.allowSceneActivation = true; }
最後的效果以下:code
上述的進度條雖然解決了100%顯示的問題,但因爲進度條的數值更新不是連續的,因此看上去不夠天然和美觀。爲了看上去像是在連續加載,能夠每一次更新進度條的時候插入過渡數值。這裏我採用的策略是當得到AsyncOperation.progress
的值後,不當即更新進度條的數值,而是每一幀在原有的數值上加1,這樣就會產生數字不停滾動的動畫效果了,迅雷中顯示下載進度就用了這個方法。htm
private IEnumerator StartLoading_4(int scene) { int displayProgress = 0; int toProgress = 0; AsyncOperation op = Application.LoadLevelAsync(scene); op.allowSceneActivation = false; while(op.progress < 0.9f) { toProgress = (int)op.progress * 100; while(displayProgress < toProgress) { ++displayProgress; SetLoadingPercentage(displayProgress); yield return new WaitForEndOfFrame(); } } toProgress = 100; while(displayProgress < toProgress){ ++displayProgress; SetLoadingPercentage(displayProgress); yield return new WaitForEndOfFrame(); } op.allowSceneActivation = true; }
displayProgress
用來記錄要顯示在進度條上的數值,最後進度條的動畫以下:對象
對比第一種的進度條
若是在加載遊戲主場景以前還須要解析數據表格,生成對象池,進行網絡鏈接等操做,那麼能夠給這些操做賦予一個權值,利用這些權值就能夠計算加載的進度了。若是你的場景加載速度很是快,那麼可使用一個假的進度條,讓玩家看上幾秒鐘的loading動畫,而後再加載場景。總之進度條雖然小,但要作好也是不容易的。