Unity3d异步记载场景&制作Loading场景进度条

来源:互联网 发布:c语言getint()方法 编辑:程序博客网 时间:2024/06/06 15:35

Unity3d异步记载场景&制作Loading场景进度条

  • 场景进度条作用

对于大多数应用来说,进度条都是必不可少的,如果你的场景切换中没有进度条,而你的游戏正在加载场景出现卡顿现象,用户便有可能觉得你的应用有问题而放弃继续使用,甚至卸载。而进度条可以有效地解决场景加载过程中用户等待的过程。提升用户体验。

  • 场景进度条书写方法

在Unity3D中提供了SceneManager,我们将会使用其中的SceneManager.LoadSceneAsync方法,该方法可以用于异步加载场景资源。该方法返回一个 AsyncOperation类型的返回值,该返回值有两个重要的属性:1、 allowSceneActivation:当场景加载完成后是否自动显示;2、progress:一个介于0-1之间的值,可以表示加载的进度。
以及以下方法

        StartCoroutine("LoadScene");

Coroutine即为协同程序,就相当于开了一个线程。StartCoroutine即是开了一个新线程。StartCoroutine(string methodName)和StartCoroutine(IEnumerator routine)两个构造方法。此两种区别在于使用字符串作为参数可以开启线程并随时可以终止线程,相反使用IEnumerator 作为参数只能等待线程的自己结束而不能随时终止;另外使用字符串作为参数时,开启线程时最多只能传递一个参数,并且性能消耗会更大一点,而使用IEnumerator 作为参数则没有这个限制。

进度条多种问题

  • 场景进度条报错

Scene ‘StarTrooper’ (-1) couldn’t be loaded because it has not been added to the build settings or the AssetBundle has not been loaded.
对于这种类型的报错,原因是因为你没有把你的场景加到你的build setting中,在Unity3d的File菜单中的build setting中添加你的场景,便不会再报此种错误。

  • 进度条显示不连续

进度条显示不连续,而是停顿一下直接到一个数值,最后在没有显示100%就情况下就切换到新场景了。它的原因是因为SceneManager.LoadSceneAsync每一次加载一些游戏资源便给出一个progress值,当游戏资源并不是完全连续的,所以不可能做到从1到100连续变化。所以我们用以下代码来完成

    if (slider.value < async_operation.progress) {        slider.value++;    }    if (slider.value==100) {        async_operation.allowSceneActivation = true;    }

即我们采取的是不断诸帧+1,直到slider.value为一百方至。

  • 进度条到百分之九十就停止

查阅后发现,把allowSceneActivation设置为false后,Unity就只会加载场景到90%,剩下的10%要等到allowSceneActivation设置为true后才加载。。。所以代码改为如下。

    if(slider.value<async_operation.progress*100+10){        slider.value++;    }    if (slider.value==100) {        async_operation.allowSceneActivation = true;    }
  • 场景进度条最终代码
using UnityEngine;using UnityEngine.UI;using System.Collections;using UnityEngine.SceneManagement;public class Slider_value : MonoBehaviour {public Slider slider;public GameObject panel;private AsyncOperation async_operation;// Use this for initializationvoid Start () {    StartCoroutine("LoadScene");    slider.value = 0;    async_operation.allowSceneActivation = false;}// Update is called once per framevoid Update() {    if (async_operation != null) {        if(slider.value<async_operation.progress*100+10){                slider.value++;            }            if (slider.value==100) {                async_operation.allowSceneActivation = true;            }        }    }IEnumerator LoadScene() {    async_operation=SceneManager.LoadSceneAsync("StarTrooper");        yield return async_operation;    }}
0 0