unity之加载场景
游戏中的Loading分为:静态Loading和动态Loading。
简单形象的做个比喻:
静态Loading可能就是一张背景图。而动态的Loading就是在读取的同时有一个东西在“转圈”。
1.静态Loading:
执行Application.LoadLevel(“name”);同步方法来加载你的场景。
2.动态Loading:
执行 AsyncOperation async = Application.LoadLevelAsync(“MyBigLevel”); 方法就可以异步加载场景。
注意:因为静态加载用户体验不是很好,所以建议大家都采用动态加载方法。
一些常见问题:
一. 游戏是否可以只做一个场景?
可以,执行 GameObject.Instantiate(“prefabName”) 方法来读取。但是游戏只做一个场景有两个致命的问题。
1.Loading界面没动画或者动画很难看
因为有个办法可以有动画,比如把你的读取场景的方法拆成3个,用协同任务来依次执行这三个方法,因为协同任务没执行一个后,会调用一下所有脚本的Update,所以按照这个逻辑你界面的动画就可以动3下。就算做出来了动画动的也会非常难看!!
2.内存的卸载完全需要你自己手工维护
Unity对读取的内存有一个缓存池的概念,如果你采用它的标准方式来切换场景,那么Unity会在切换场景的时候自动帮你把没有被引用的资源对象从内存中卸载掉。但是你现在是一个场景了,那么卸载内存的东西就要万全自己手工维护了。。
二.异步加载场景为什么最后会卡一下
这个罪魁祸首就是Unity不支持多线程。游戏加载被你分成了两部分、第一部分是加载场景,你可以把场景上已知的模型都保存在Scene上面,此时你在调用异步加载场景的时候会进度动画会非常的均匀。加载场景你可以理解成Unity自己在多线程加载,有可能他的后台也是同步,但是我们看不到源码从它的效果上来看它加载场景是多线程。
但是问题出在了第二步上,因为你需要加载未知模型,举个例子,当你进副本加载场景的时候,场景可不知道你身上带了那几个英雄。所以场景加载完毕后你还需要去加载的这些模型。无论你是用协同任务也好,还是在方法里面执行也好,因为Unity没有多线程,一般为了更快的能进游戏这里的加载都会选择同步加载,所以你会发现大部分游戏进度条加载到最后都会卡一下。
为了解决这个问题,在加载的时候一定要避免加载场景后自己写的哪个同步加载的方法,尽量让他执行更少的加载。
1.尽可能让场景多包含一些资源,我看有些人为了节省资源,打开场景以后动态的加载一些地面上的小物件。我觉得这种情况多做几个场景就可以了,不用在一个同步方法里出力过多的东西。
2.人物模型可以考虑预加载,也可以考虑常驻内存。。因为你的人物模型可能不止在战斗中才会被使用。
三、减少Loading的次数
//参数1 加载场景之前做的事情 //参数2 新加载的场景名 //参数3 加载场景后要做的事情 public void LoadScene(System.Action before, string sceneName, System.Action end) { before(); if(Application.loadedLevelName != sceneName) { } //异步加载场景, 加载完毕后 调用 end方法。 else { end(); } }