[Unity]【筆記】Loading讀取畫面,百分比緩動

momo的文章

其實momo寫的就非常清楚了

基本上大家都會異步加載的方式來實現loading畫面
畢竟遊戲大了,只用loadlevel會lag 卡卡的

要了解異步,要先了解AsyncOperation類別

有四個Variables

目前要用到的只有兩個

allowSceneActivation和progress

progress的取值在0.1~1之間,不會等於1
為了計算百分比,以下會x100來計算

一般來說,我們都是 A場景到C場景,中間會有個B場景當LOADING畫面

而通常我們載入一些資源較少的場景,loading會很快,這樣你可能連影都沒看到就跳到下個場景了

所以allowSceneActivation 就是用來加載完成後,什麼時候你才要讓他跑下個場景
設為false的話就是永遠不跳到下個場景,直到true才會

======================


async.allowSceneActivation = false;
       
        while (async.progress < 0.9f)
        {
            toProgress = (int)async.progress * 100;
            while (displayProgress < toProgress)
            {
                ++displayProgress;
                SetLoadingSlider(displayProgress);
                yield return new WaitForEndOfFrame();
            }
            yield return new WaitForEndOfFrame();
        }
        toProgress = 100;
        while (displayProgress < toProgress)
        {
            ++displayProgress;
            SetLoadingSlider(displayProgress);
            yield return new WaitForEndOfFrame();
        }


基本上跟momo那篇一樣,不過IEnumerator loadScene()內在加入上面代碼
async.allowSceneActivation = false; 就是加載完之後不允許直接跳下個畫面

async.progress

讀取進度通常會小於0.9的時候就跳畫面了,因此用兩個while迴圈
一個是在0.9前,一個是在0.9後,也就是讀取完場景前跟讀取完場景後

1.第一個while迴圈,還沒讀取完
當displayProgress小於當前讀取進度的百分比
就++,然後利用 SetLoadingSlider ,返回畫面的進度條讓他緩動 (( 就是1~90,每次跳躍都可以看到1.2.3.4這樣跳,才不會一開始10% 數字立馬跳到90%

2.第二個while迴圈,讀取完後

因為async.progress不會等於1,也就是 toProgress 不會讀取到100% ((詳細讀第一個迴圈

手動的把toProgress設為100 後進入第二個迴圈
接著跟上面一樣,就完成啦~


完整代碼  :
(感謝 [鴿子獸] 葷教授 的修正 )

using UnityEngine;
using System.Collections;
using UnityEngine.UI;


public class Loading : MonoBehaviour
{



    AsyncOperation async;
    int Progress
    {
        get { return _progress; }
        set {
            _progress = value;
            if(_progress>=100) { async.allowSceneActivation = true; }
        }
    }
    int _progress = 0;
    public Slider LoadingSlider;


    void Start()
    {
        StartCoroutine(loadScene());
    }

    IEnumerator loadScene()
    {
        int Progress = 0;
        int toProgress = 0;
        async = Application.LoadLevelAsync(Globe.loadName);
        async.allowSceneActivation = false;

        while (async.progress < 0.9f)
        {
            toProgress = (int)async.progress * 100;
            while (Progress < toProgress)
            {
                ++Progress;
                SetLoadingSlider(Progress);
                yield return new WaitForEndOfFrame();
            }
            yield return new WaitForEndOfFrame();
        }
        toProgress = 100;
        while (Progress < toProgress)
        {
            ++Progress;
            SetLoadingSlider(Progress);
            yield return new WaitForEndOfFrame();
        }

    }

    void SetLoadingSlider(int p_progress)
    {
        float tmp = (float)((float)p_progress / 100);
        LoadingSlider.value = tmp;
    }
}
Share:

5 則留言:

  1. 能請問一下 他讀取完滿了 可是沒有跳到遊戲場景呢

    回覆刪除
  2. async.allowSceneActivation = ture就可以跳了 上面一開始設為false是怕他跳太快 (先暫停跳的動作去跑進度條 )

    回覆刪除
  3. 給個建議幫忙補完,其實上方的Code內的progress並沒有用到,我的建議是將Progress做成get&set的方式,直接取代掉displayProgress(也就是Progress就是顯示的數值),然後在Set內檢查,當Progress==100時就跳場景
    修正後大概像以下這樣

    using UnityEngine;
    using System.Collections;
    using UnityEngine.UI;

    public class NewVersionLoading : MonoBehaviour
    {


    AsyncOperation async;
    int progress
    {
    get { return _progress; }
    set
    {
    _progress = value;
    if (_progress >= 100) { async.allowSceneActivation = true; }
    }
    }
    int _progress = 0;
    public Slider LoadingSlider;


    void Start()
    {
    StartCoroutine(loadScene());
    }

    IEnumerator loadScene()
    {
    progress = 0;
    int toProgress = 0;
    async = Application.LoadLevelAsync(Globle._loadIndex);
    async.allowSceneActivation = false;

    while (async.progress < 0.9f)
    {
    toProgress = (int)async.progress * 100;
    while (progress < toProgress)
    {
    ++progress;
    SetLoadingSlider(progress);
    yield return new WaitForEndOfFrame();
    }
    yield return new WaitForEndOfFrame();
    }
    toProgress = 100;
    while (progress < toProgress)
    {
    ++progress;
    SetLoadingSlider(progress);
    yield return new WaitForEndOfFrame();
    }

    }

    void SetLoadingSlider(int progress)
    {
    float tmp = (float)((float)progress / 100);
    LoadingSlider.value = tmp;
    }

    }

    回覆刪除
    回覆
    1. 這樣就可以顯示數值滿的時候直接切場景

      刪除
    2. 感謝你的建議!
      沒注意到上面的progress忘記用了XD
      現在補完囉 感恩~

      刪除