进度条加载实现

发布于 2018-02-06  947 次阅读


监听Unity加载事件

最终实现效果

2018-02-06 at 下午4.42

我们可以通过在脚本初始化时,对Unity中SceneManager中的sceneLoaded事件进行监听。
可以通过SceneManager.GetActiveScene().name获得当前的场景名。

SceneManager.sceneLoaded += (scene, mode) => {

    sceneLoaded?.Invoke(scene.name);
};

提供切换场景的入口

外部调用时,提供切换场景的API,并对场景名进行比对。
只有在切换场景时,我们才调用异步加载场景函数AsyncLoadScene()
当加载结束时,我们打开对应的XXX

if (oldScene == scene) {

    // 打开
} else {
    sceneLoaded = (sceneName) => {

       if (sceneName == scene) {

          sceneLoaded = null;
          // 打开
       }
    };
    onoHelper.StartCoroutine(AsyncLoadScene(scene));
}

异步加载Scene处理

为了实现进度条根据当前场景的加载速度变化,并实现一个匀速效果,我们需要做如下处理。

当我们将allowSceneActivation设为false时,Unity只会加载到0.9。
所以在加载时,退出条件写为 < 0.9f。
这时场景已经加载完毕了,但是在90%~100%的数据需要我们手动计算。
在进度条读到100时,我们将allowSceneActivation设为true。

private IEnumerator AsyncLoadScene(string scene) {

    int displayProgress = 0;
    int toProgress = 0;
    AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(scene);
    asyncLoad.allowSceneActivation = false;

    while (asyncLoad.progress < 0.9f) {

        toProgress = (int)asyncLoad.progress * 100;
        while (displayProgress < toProgress) {

            ++displayProgress;
            // set 对应的loading progress
            yield return new WaitForEndOfFrame();
        }
    }

    toProgress = 100;

    while (displayProgress < toProgress) {

        ++displayProgress;
        // set 对应的loading progress
        yield return new WaitForEndOfFrame();
    }

    asyncLoad.allowSceneActivation = true;
}

What doesn’t kill you makes you stronger.