Unity游戏开发文档(3.2.1):异步加载游戏场景

前言

   该文档为《Unity游戏开发文档(3):Dancing Line》的附属文档,亦可看作是单独的技术总结文档。



综述

当游戏需要从一个 场景(Sence) 跳转到另外一个场景时,如果下一个场景需要加载的资源很多,那么游戏会便会卡在上一个场景不动,直到下一个场景完成加载后游戏才会进入。对于玩家来说,每次在加载新场景的时候都要等一大段时间有什么都做不了,是很令人不爽的,游戏体验也大打折扣了。

所以基本所有的游戏在加载大场景之前,都会先让游戏进入一个可以瞬间完成加载的小场景中,在小场景中显示加载进度条,或者播放一些小动画,更有甚者会内嵌一个小游戏,同时并行地加载大场景。当大场景完成加载后,游戏便跳出当前的小场景,进入到大场景中,继续执行正常的游戏流程。这样便可以避免等待场景切换带来的低游戏体验了。


异步加载场景

异步加载场景的逻辑如下:

  1. 假设有三个场景,A场景是游戏当前所在场景,B场景是过渡场景,C场景是最终需要进入的场景。
  2. 在A场景时,我们首先加载并进入到B场景。
  3. 随后在B场景中,我们创建一个协程,并命令协程加载C场景。在C场景加载的这段时间里,游戏会继续执行B场景的游戏逻辑。
  4. C场景完成加载后会协程返回到B场景的主线逻辑,B场景的主线逻辑得知协程退出后,会立刻进入C场景。
  5. 游戏开始执行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 内置的 TextTextMeshPro 组件实现,我们在每一帧获取场景当前的加载进度,然后把数值更新到文本内容上即可。

在这里插入图片描述

红框处即是用于显示进度的组件,由于未进行游戏,所以没有对应的信息显示

进度条可以用 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值