问题阐述:
一般来说,在加载场景的时候,会因为所加载资源的大小、复杂度、电脑配置等因素导致加载过程耗费一定的时间。虽然这个加载时间是不可避免的,但是在这一小段卡着的时间里如果就这样卡着的话会大大降低玩家体验。
所以很多游戏在加载过程中都会显示加载进度条,以及一些加载动画之类的东西。
但是如果直接采用SceneManager.LoadScene()加载的话,直到场景加载完,整个程序是做不了其他事情的。也就是说,这个函数是一个同步加载的方法。
那要在加载场景的同时,显示进度条等动画的话,就需要采用异步加载场景的手段。异步加载就是,在加载这个资源的同时,程序的其他部分照常运行,不会因此而卡住。
这样的话,一方面程序在加载场景,另一方面可以控制画面上的加载进度条、动画等元素的行为活动。
同时,要实现进度条的话,得获取到场景加载的进度,而这个Unity早就为我们封装好了函数可以直接调用,非常便捷。
要实现异步加载场景,同时追踪加载的进度,具体代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using TMPro;
public class SceneLoader : MonoBehaviour
{
// Start is called before the first frame update
public TextMeshProUGUI text;
void Start()
{
StartCoroutine(LoadScene());
text.text = "";
}
IEnumerator LoadScene()
{
AsyncOperation operation = SceneManager.LoadSceneAsync("Main",LoadSceneMode.Additive);
operation.allowSceneActivation = false;
float progress = 0;
while (progress < 1f)
{
progress = operation.progress;
text.text +=Time.time+"--loading:" + progress+"\n";
if (progress >= 0.9f)
{
progress = 1.0f;
text.text += Time.time + "--Load Complished!"+"\n";
operation.allowSceneActivation = true;
}
yield return null;
}
}
// Update is called once per frame
void Update()
{
text.text += Time.time + "Update" + "\n";
}
}
以上代码实现了异步加载Main场景,加载完成后并显示。同时在画面上显示加载进度信息。(我这里为啥用UI显示而不是直接Debug.Log()到后面就知道了)。
但是在运行的时候发现,开始加载后,一切都会卡住,然后直接跳到0.9加载结束(因为设置了operation.allowSceneActivation = false(即加载场景但是并不激活它),所以异步只会加载到0.9,直到设置其为true则激活场景并且加载结束)。输出信息如下图:
可以看到,加载过程中Update也被停滞了,那这样就还是同步加载并不是异步加载了。
如果这样的话,制作进度条就是一开始进度为0,卡了几秒后直接进度跳满。那这样进度条就没啥意义了。
问题原因:
找了半天暂时没找到为啥编辑器模式下异步加载不异步。。。而且Unity源码也看不着。。。
以后找到了原因再补吧。
解决办法:
虽然编辑器模式下出现这个问题,但是打包运行的时候就是正常的异步加载。(如下图)
可以看到每一帧都输出了加载进度,并且也没有卡住然后直接跳到0.9这种情况。