Unity 异步加载场景
Posted shadowsghost
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity 异步加载场景相关的知识,希望对你有一定的参考价值。
回顾场景同步加载
SceneManager.LoadScene(“”);//传入场景名,就可以实现同步切换了。
场景同步加载的缺点:
在切换场景时,Unity会删除当前场景上所有对象,并且去加载下一个场景的相关信息。
如果当前场景对象过多或者下一个场景对象过多,这个过程会非常的耗时,会让玩家感受到卡顿。所以异步切换就是来解决该问题的。
场景异步加载
异步加载的两种方式
1.异步加载 第一种方式:通过事件回调函数异步加载
异步加载场景的API:SceneManager.LoadSceneAsync(“场景名称”);
如果想要加载结束之后做一些逻辑处理的话该怎么做?
我们可以看到,异步加载场景函数的返回值类型AsyncOperation中有一个event类型的成员。Event是事件类型,相当于一个更加安全的委托(这里可以把它当做委托来理解)。当Unity异步加载完场景之后,会自动调用completed中的函数。
例如,下面这个OverLoad()方法是我们想要场景加载结束之后去调用的方法
private void LoadOver(AsyncOperation ao)
print("LoadOver");
那么这样就可以让Unity在场景加载结束之后去自动调用方法了,
AsyncOperation ao=SceneManager.LoadSceneAsync("场景1");
ao.complette+=LoadOver;
通过事件回调函数来实现异步加载的话,当场景加载结束之后,如果你希望去做一些逻辑处理的话,就在事件中添加监听函数就可以了。
2.异步加载 第二种方式:通过协程异步加载
IEnumeratior LoadScene(string name)
//异步加载场景
AsyncOperation ao=SceneManager.LoadSceneAsync(name);
//unity内部的协程协调器法线是异步加载类型的返回对象就会等待
//等待异步加载结束后才会继续执行迭代器函数中后面的步骤
yield return ao;
Yield return 一个AsyncOperation类型,Unity中的协程协调器就会等待加载完毕之后,再去处理之后的逻辑。
需要加载场景的时候,开启协程来启动场景加载
StartCoroutine(LoadScene("场景1"));
注意:加载场景之后,原有场景中的所有东西都会被删除,包括脚本。这就意味着,当切换场景的时候,当前脚本就失效了,因此加载场景完毕之后的逻辑都不会被执行了。如果想要脚本没有问题,就要让脚本依附的对象过场景不移除。
DontDestroyOnLoad(this.gameObject);
两种方式对比:
第一种方式更加简单,但是它一定要在场景加载结束之后才能去执行指定的逻辑。
第二种方式虽然复杂,但是可以让我们在异步加载中做一些事情。
比如,我们可以在异步加载过程中去显示加载的进度条。
如何实现进度条更新
第一种方式:利用异步加载的进度去更新
在异步加载类型AsyncOperation中,成员progress就是来获取加载进度的,isDone表示是否加载完毕。
具体实现
第二种:根据你的游戏规则,自己定义进度条变化的条件
比如,场景加载结束,更新20%的进度,接着去加载场景中的其他信息,比如动态加载怪物,加载结束后让进度条再增加20%,接着再通道加载物品,更新进度条……
总结
场景异步加载有两种方式
1.通过事件回调函数
2.协程异步加载
1.事件回调函数
优点:写法简单,逻辑清晰
缺点:只能加载完场景做一些事情 不能再加载过程中处理逻辑
2.协程异步加载
优点:可以在加载过程中处理逻辑,比如进度条更新等
缺点:写法较为麻烦,要通过协程
unity3d 异步加载场景代码
1 using UnityEngine; 2 using System.Collections; 3 4 /// <summary> 5 /// 加载场景 6 /// </summary> 7 public class LoadSence : MonoBehaviour { 8 9 10 private IEnumerator StartLoading(string SenceName) 11 { 12 int displayProgress = 0; 13 int toProgress = 0; 14 AsyncOperation op = Application.LoadLevelAsync(SenceName); 15 op.allowSceneActivation = false; 16 while (op.progress < 0.2f) 17 { 18 toProgress = (int)op.progress * 100; 19 while (displayProgress < toProgress) 20 { 21 ++displayProgress; 22 SetLoadingPercentage(displayProgress); 23 yield return new WaitForEndOfFrame(); 24 } 25 } 26 27 toProgress = 100; 28 while (displayProgress < toProgress) 29 { 30 ++displayProgress; 31 SetLoadingPercentage(displayProgress); 32 yield return new WaitForEndOfFrame(); 33 } 34 yield return new WaitForSeconds(1.0f); 35 op.allowSceneActivation = true; 36 } 37 38 39 40 // Use this for initialization 41 void Start () { 42 43 Time.timeScale = 1.0f; 44 45 switch (GameManager.CurrentSenceIndex) 46 { 47 48 case 1: 49 50 GameManager.m_NextSence = "linjiankongdi"; 51 52 break; 53 case 2: 54 GameManager.m_NextSence = "linjiankongdi2"; 55 56 break; 57 case 3: 58 59 GameManager.m_NextSence = "huangyejiaotang"; 60 61 break; 62 case 4: 63 64 GameManager.m_NextSence = "huangyejiaotang2"; 65 66 break; 67 68 default: 69 break; 70 } 71 72 StartCoroutine(StartLoading(GameManager.m_NextSence)); 73 //StartCoroutine(StartLoading("SenceOne")); 74 75 } 76 77 public UISlider m_UISlider; 78 79 void SetLoadingPercentage(int progress) 80 { 81 m_UISlider.value = (float)progress / 100.0f; 82 } 83 84 85 86 87 // Update is called once per frame 88 void Update () { 89 90 } 91 }
以上是关于Unity 异步加载场景的主要内容,如果未能解决你的问题,请参考以下文章