U2L11——场景异步切换

本章代码关键字

1
SceneManager.LoadSceneAsync()    //异步加载场景的方法,返回一个AsyncOperation,可以用回调函数或者协程来操作

场景同步切换

在入门的实践已经过同步切换了——>场景同步切换

1
SceneManager.LoadScene("Lesson20");

场景同步切换的缺点

在切换场景时Unity会删除当前场景上的所有对象,并且去加载下一个场景的相关消息
如果当前场景对象过多或者下一个场景对象过多,这个过程会非常的耗时,且会让玩家感受到卡顿
所以异步切换就是来解决该问题的

场景异步切换

场景异步加载和Resources资源异步加载,几乎一致,有两种方式

  1. 通过事件回调函数
  2. 协程异步加载

它们的优缺点表现和资源异步加载 也是一样的
不同的点在于,只要执行了SceneManager.LoadSceneAsync()​,就算不使用回调函数或者协程都会在加载完成后自动切换场景
由于场景异步切换方法返回的是AsyncOperation​,因此它的成员都可以如Resources资源异步加载一样使用,使用方法参考资源异步加载,这里不再记录

通过事件回调函数异步加载

  • 优点:写法简单,逻辑清晰,不需要担心切换场景后能否运行
  • 缺点:只能加载完场景后做一些事情不能在加载过程中更新逻辑
1
2
3
4
5
6
7
8
9
10
11
12
13
//通过事件回调函数 异步加载
AsyncOperation ao = SceneManager.LoadSceneAsync("Lesson20");
//当场景异步加载结束后 就会自动调用该事件函数 我们如果希望在加载结束后 做一些事情 就可以在该函数中写处理逻辑
ao.completed += (a) =>
{

};
ao.completed += LoadOver;

private void LoadOver(AsyncOperation a)
{

}

通过协程异步加载

  • 优点:可以在加载过程中处理逻辑,比如进度条更新等
  • 缺点:写法较为麻烦,要通过协程,需要注意如果协程依附的对象在切换场景途中被移除,后面的内容将不会被执行

需要注意的是 加载场景会把当前场景上 没有特别处理的对象 都删除了
所以 协程中的部分逻辑 可能是执行不了的
解决思路:让处理场景加载的脚本依附的对象 过场景时 不被移除

协程的好处 是异步加载场景时 可以在加载的同时 做一些别的逻辑

比如我们可以在异步加载过程中去更新进度条

  • 第一种:就是利用 场景异步加载 的进度去更新 但是 不是特别明确 一般也不会直接用

  • 第二种:

    就是根据你游戏的规则 自己定义 进度条变化的条件
    场景加载结束 更新20%的进度
    接着去加载场景中的其他消息,比如动态加载怪物,动态加载物品,这时 进度条 再更新20%
    动态加载 场景模型
    这时 就认为 加载结束了 进度条顶满,隐藏进度条

1
2
DontDestroyOnLoad(this.gameObject);    //这样过场景时,此对象不会被移除
StartCoroutine(LoadScene("Lesson20"));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
IEnumerator LoadScene(string name)
{
//第一步
//异步加载场景
AsyncOperation ao = SceneManager.LoadSceneAsync(name);
//向Unity协程调度器返回异步加载类型的返回对象,
//Unity就会等待异步加载结束 才会继续执行 迭代器函数中后面的步骤
print("异步加载中");
//协程的好处 是异步加载场景时 可以在加载的同时 做一些别的逻辑
//比如我们可以在异步加载过程中去更新进度条
//第一种 就是利用 场景异步加载 的进度 去更新 但是 不是特别明确 一般也不会直接用
while (!ao.isDone)
{
print(ao.progress);
yield return null;
}
yield return ao;
//第二步
//注意!如果协程依附的对象在切换场景途中被移除,后面的内容是不会被执行的!
print("异步记载后");
}