1. 程式人生 > 其它 >Unity 非同步載入 進度條

Unity 非同步載入 進度條

當我們進行遊戲開發時,時常會進行場景切換,如果下個場景較大,切換時就會出現卡頓現象,甚至看起來像是"宕機",非常影響使用者體驗,我們這時就可以運用非同步載入,在介面上顯示載入的進度條以提升使用者體驗,接下來我們就簡略聊聊非同步載入吧.

我要實現的功能是這樣的:首先,第一個場景是一個UI介面,點選"開始載入"按鈕進行載入下一場景,場景載入完成後自動跳轉,通過文字和進度條顯示載入進度,如圖:

然後,第二個場景,也就是我們要載入的場景名為"Demo Valley",注意此場景必須加入到unity的build中才行(File->Build Setting):

接下來就該上程式碼了,如下(此指令碼掛於Canvas上):

 1 using UnityEngine;
 2 using UnityEngine.SceneManagement;//注意引用名稱空間
 3 using System;
 4 using UnityEngine.UI;
 5 
 6 public class LoadScene : MonoBehaviour
 7 {
 8     Slider slider;//滑動條
 9     Text text;//文字
10     Button but;//按鈕
11     // 載入進度
12     float loadPro = 0;
13 
14     // 用以接受非同步載入的返回值
15     AsyncOperation  AsyncOp = null
; 16 17 void Start() 18 { 19 Debug.Log("開始載入"); 20 21 slider = transform.Find("Slider"). GetComponent<Slider>(); 22 slider.value = 0; 23 text = transform.Find("Text").GetComponent<Text>(); 24 but = transform.Find("Button").GetComponent<Button>();
25 but.onClick.AddListener(StartLoad);//繫結按鈕事件 26 27 } 28 29 //點選按鈕,開始載入下一場景,文字和進度條顯示載入進度 30 void StartLoad() 31 { 32 AsyncOp = SceneManager.LoadSceneAsync("Demo Valley",LoadSceneMode.Single);//非同步載入場景名為"Demo Valley"的場景,LoadSceneMode.Single表示不保留現有場景 33 AsyncOp.allowSceneActivation = false;//allowSceneActivation =true表示場景載入完成後自動跳轉,經測,此值預設為true 34 } 35 36 void Update() 37 { 38 if (AsyncOp!=null)//如果已經開始載入 39 { 40 loadPro = AsyncOp.progress; //獲取載入進度,此處特別注意:載入場景的progress值最大為0.9!!! 41 } 42 if (loadPro >= 0.9f)//因為progress值最大為0.9,所以我們需要強制將其等於1 43 { 44 loadPro = 1; 45 } 46 slider.value = Mathf.Lerp(slider.value, loadPro,1*Time.deltaTime);//滑動塊的value以插值的方式緊跟進度值 47 if (slider.value > 0.99f) 48 { 49 slider.value = 1; 50 AsyncOp.allowSceneActivation = true; 51 } 52 text.text =string.Format("{0:F0}%", slider.value*100);//文字中以百分比的格式顯示載入進度 53 } 54 }

此處需要注意的地方有以下幾點:

  1. 載入場景的progress值最大為0.9!!!不知道其用意為何.
  2. AsyncOp.allowSceneActivation 表示場景載入完成後,是否自動跳轉,為true時自動跳轉.網上有說當其為false時,場景進度只加載至0.9不再載入,當將其更改為true後,繼續載入剩下的0.1,因為沒有想出合適的檢測方法,所有沒有檢測真假。
  3. 本文提到的非同步載入本身就是運用的協程進行的載入!網上有些用Coroutine和LoadSceneAsync合用進行的非同步載入,不明其意.
  4. 在實際開發中,進度條的顯示有可能會安排在一個新建的過度場景中,原理跟本文的原理相同,無非就是把非同步載入的指令碼掛在過度場景的Start()函式中而已.
  5. 此案例中載入場景我們用的SceneManager.LoadSceneAsync()來載入場景,當我們只加載一些預製體時,Resources.LoadAsync()的用法和注意事項與其基本相同.
  6. 我們之所以在StartLoad函式中將AsyncOp.allowSceneActivation = false,等slider.value > 0.99f時再使其為true,是為了避免UI中進度條還未達到100%時場景已經跳轉的情況出現;而使用插值的方式使進度條的值趨近實際的載入進度是為了避免UI中進度條已經達到100%,但是場景還未載入完成的情況出現,也就是說,我們使用插值實際上就是在為場景載入的最後0.1爭取時間.