前言
该文档为《Unity游戏开发文档(3):Dancing Line》的附属文档,亦可看作是单独的技术总结文档。
综述
当游戏需要从一个 场景(Sence) 跳转到另外一个场景时,如果下一个场景需要加载的资源很多,那么游戏会便会卡在上一个场景不动,直到下一个场景完成加载后游戏才会进入。对于玩家来说,每次在加载新场景的时候都要等一大段时间有什么都做不了,是很令人不爽的,游戏体验也大打折扣了。
所以基本所有的游戏在加载大场景之前,都会先让游戏进入一个可以瞬间完成加载的小场景中,在小场景中显示加载进度条,或者播放一些小动画,更有甚者会内嵌一个小游戏,同时并行地加载大场景。当大场景完成加载后,游戏便跳出当前的小场景,进入到大场景中,继续执行正常的游戏流程。这样便可以避免等待场景切换带来的低游戏体验了。
异步加载场景
异步加载场景的逻辑如下:
- 假设有三个场景,A场景是游戏当前所在场景,B场景是过渡场景,C场景是最终需要进入的场景。
- 在A场景时,我们首先加载并进入到B场景。
- 随后在B场景中,我们创建一个协程,并命令协程加载C场景。在C场景加载的这段时间里,游戏会继续执行B场景的游戏逻辑。
- C场景完成加载后会协程返回到B场景的主线逻辑,B场景的主线逻辑得知协程退出后,会立刻进入C场景。
- 游戏开始执行C场景逻辑。
在 Dancing Line 中,我们需要做的是从 Menu 场景经过 Load 场景的过渡,进入到 Game场景。具体的代码实现如下:
- 在A场景中,由于我们是通过点击按钮触发场景切换,所以代码还包含了按钮监听点击事件的逻辑
using UnityEngine.SceneManagement;
private Button button;
void Start() {
button = transform.GetComponent<Button>();
button.onClick.AddListener(LoadGameScene);
}
public void LoadGameScene() {
Destroy(this);
SceneManager.LoadScene(load_scene); // Load the "load_scene" scene
}
- B场景加载C场景的实现代码
using UnityEngine.SceneManagement;
void Start () {
StartCoroutine(LoadScene()); // Begin to asynchronous load game scene
}
IEnumerator LoadScene() // Asynchronous load game scene
{
async = SceneManager.LoadSceneAsync(GlobalData.game_scene);
yield return async;
}
显示加载进度
在过渡场景中游戏应该做些什么来为玩家排闷解乏,那就需要开发者发挥各自的想象力了,萝卜青菜各有所爱。在这里我们会介绍最常见也是最基本的形式,即为玩家显示加载百分比进度以及进度条。
百分比进度可以用 Unity GUI 内置的 Text 或 TextMeshPro 组件实现,我们在每一帧获取场景当前的加载进度,然后把数值更新到文本内容上即可。
进度条可以用 Unity GUI 内置的 Image 组件实现。我们首先需要准备长条形的图片,把它设为 Unity Image。然后在每一帧,通过我们获取得到的场景加载进度来设置图片的可显示部分,即可实现进度条功能。
下方是具体的代码实现:
private int progress = 0;
private Image progress_bar;
private TextMeshProUGUI progress_text;
private AsyncOperation async = null;
void OnGUI() {
progress_text.text = progress + "%"; // Update the text for displaying realtime progress of scene loading
progress_bar.fillAmount = progress / 100f; // Update the progress bar base on the loading progress
if (progress == 100) {
progress_text.text = "OK"; // Display "OK" when scene loading is complete
}
}
void Start () {
StartCoroutine(LoadScene()); // Begin to asynchronous load game scene
}
void Update() {
progress = (int)(async.progress * 100);
}
最终效果
额…要加载的游戏场景不是很大,一下子就完成加载了,所以最终我们只能看到过渡的场景闪了一下就跳到游戏场景了。
参考资料
异步加载游戏场景与异步加载游戏资源进度条: http://www.xuanyusong.com/archives/1427
Unity 中场景切换:https://www.cnblogs.com/zsb517/p/4113538.html
LoadSceneAsync出现的问题:https://blog.csdn.net/qq_43040880/article/details/108695349
SceneManager.LoadScene调用后新场景会变暗的问题:https://blog.csdn.net/qq_42965798/article/details/89670818