Unity异步场景加载
在游戏中,场景加载是很常用的功能。如果要在加载的时候让当前的场景还能正常运行,或者加载时能有一个包含进度条之类组件的加载界面,就应该采取异步的场景加载方式。
¶同步加载
在讲异步加载以前,先说同步加载。
当执行同步加载时,正在运行的场景会被阻塞,产生卡顿,这种方法适合小型的、不怎么需要获取读取进度的场景的加载。如在地牢中切换到另一个房间,读取完成之前当前房间中的一切都静止不动,这种情况应该是用同步加载实现的。
Unity使用SceneManager
类的静态方法LoadScene实现同步的场景加载。由于是静态方法,不需要对SceneManager
类进行实例化,只要使用命名空间using UnityEngine.SceneManagement;
就可直接通过SceneManager.LoadSceneAsync
访问。
1 | //方法原型: |
其中,第一个参数可以是场景的编号sceneBuildIndex
,也可以是场景的名称sceneName
。
什么是场景编号?
场景编号是工程中每个场景唯一的int
型编号,记录在Unity的File->Build Settings->Scenes in Build
中。如果没有看到你想要的场景,可以通过Build Settings中的Add Open Scenes
加入场景。
第二个参数所说的LoadSceneMode
是一个枚举类,包含Addtive
和Single
两种加载方法。前者是在保留当前场景的基础上加载其他场景,如果是临时打开一个全屏的设置界面,就可以使用这种加载方式;而后者在加载完新场景之后就不保留原来的场景,适合进行关卡的切换等。
¶异步加载
异步加载和同步加载大同小异,但是它通过C#的“协程”使得加载过程看起来是在后台运行。
1 | //方法原型: |
方法原型与同步加载非常相似,方法名也只是加了一个“Async”。但最大的不同是,LoadSceneAsync
返回的是一个AsyncOperation
类对象,用于对后台的加载过程进行监测,其中有一个比较有意思的bool
型属性allowSceneActivation
,如果将其设置为false
,加载进度public float progress
会在0.9处暂停,直到将allowSceneActivation
设置为true
时再继续加载剩下的10%。
需要注意,Unity并不支持多线程,这里使用的协程实际上是一种Unity主线程上的伪线程。在VS的线程调试窗口里也可以看到协程启动后其实仍然在原来的线程里,我认为它大概和传说中的纤程就是一种东西,而后面的几个工作线程应当是C#的CLR开辟的。
1 |
|
¶参考资料
- Unity - SceneManager.LoadScene
- Unity - SceneManager.LoadSceneAsync
- 知乎 - Unity 的多线程、协程、纤程
- CSDN - Unity多线程、线程池的使用
- CSDN - Unity异步加载场景SceneManager.LoadSceneAsync与AsyncOperation的使用
虽然是个很简单的需求,但是涉及的东西不少也不简单,我至今也没完全搞明白……