首页 > Unity3D频道 > 【你好Unity3D】 > #你好Unity3D#Unity制作Loading详解(来自我的长微博)
2014
06-14

#你好Unity3D#Unity制作Loading详解(来自我的长微博)

游戏中的Loading现在都做得很漂亮,但是归根究底就两种类型,静态Loading和动态Loading。
静态Loading可能就是一张背景图。而动态的Loading就是在读取的同时有一个东西在“转圈”。

1.静态Loading:
优点:读取场景使用同步的方法就可以,因为是同步方法所以读取的速度是最快的,也不用更新界面,因为同步执行方法的时候程序在等待读取结束。
执行Application.LoadLevel(“name”);同步方法来加载你的场景。

缺点:Loading的时候如果界面不动,那么用户体验肯定不佳,因为读取的时间如果过长用户就会误以为手机卡死了。其实我个人还是觉得最好用动态加载Loading的方式,虽然读取的时间没有静态Loading快,但是用户体验很好。

2.动态Loading:
优点:读取的时候界面可以有动画,甚至还可以做一些小游戏。场景可以异步加载,那么脚本上的Update就会每一帧都执行,所以就能做一些动态的东西。

缺点:没有缺点,嘿嘿,建议大家一定要使用动态loading、
执行 AsyncOperation async = Application.LoadLevelAsync(“MyBigLevel”); 方法就可以异步加载场景。

常见问题:

一. 游戏是否可以只做一个场景?

可以,而且我也看见过一些游戏只做一个场景,因为你所有的东西都可以动态加载来完成、比如场景模型、人物模型、场景烘培贴图等等。
执行 GameObject.Instantiate(“prefabName”) 方法来读取。
但是游戏只做一个场景有两个致命的问题。 

1.Loading界面没动画或者动画很难看
因为有个办法可以有动画,比如把你的读取场景的方法拆成3个,用协同任务来依次执行这三个方法,因为协同任务没执行一个后,会调用一下所有脚本的Update,所以按照这个逻辑你界面的动画就可以动3下。。如果你真想这么干?我劝你还是早点放弃。因为你的同步方法不会拆分的那么均匀的,就算做出来了动画动的也会非常难看!!

2.内存的卸载完全需要你自己手工维护
Unity对读取的内存有一个缓存池的概念,如果你采用它的标准方式来切换场景,那么Unity会在切换场景的时候自动帮你把没有被引用的资源对象从内存中卸载掉。但是你现在是一个场景了,那么卸载内存的东西就要万全自己手工维护了。。

二.异步加载场景为什么最后会卡一下

这个罪魁祸首就是Unity不支持多线程。游戏加载被你分成了两部分、第一部分是加载场景,你可以把场景上已知的模型都保存在Scene上面,此时你在调用异步加载场景的时候会进度动画会非常的均匀。加载场景你可以理解成Unity自己在多线程加载,有可能他的后台也是同步,但是我们看不到源码从它的效果上来看它加载场景是多线程。

但是问题出在了第二步上,因为你需要加载未知模型,举个例子,当你进副本加载场景的时候,场景可不知道你身上带了那几个英雄。所以场景加载完毕后你还需要去加载的这些模型。无论你是用协同任务也好,还是在方法里面执行也好,因为Unity没有多线程,一般为了更快的能进游戏这里的加载都会选择同步加载,所以你会发现大部分游戏进度条加载到最后都会卡一下。
为了解决这个问题,在加载的时候一定要避免加载场景后自己写的哪个同步加载的方法,尽量让他执行更少的加载。

1.尽可能让场景多包含一些资源,我看有些人为了节省资源,打开场景以后动态的加载一些地面上的小物件。我觉得这种情况多做几个场景就可以了,不用在一个同步方法里出力过多的东西。

2.人物模型可以考虑预加载,也可以考虑常驻内存。。因为你的人物模型可能不止在战斗中才会被使用。

三、减少Loading的次数
尤其是战斗场景,重复挑战同一关卡的时候,因为场景没有变化,尽量就不要在去读取场景。所以你可以写一个加载的界面,根据当前场景名 和需要加载的场景名 如果场景相同 就不去加载, 如果场景不同再去加载,这样其实能省很多时间。

欢迎关注雨松MOMO的微博

 

最后编辑:
作者:雨松MOMO
专注移动互联网,Unity3D游戏开发
捐 赠写博客不易,如果您想请我喝一杯星巴克的话?就进来看吧!

#你好Unity3D#Unity制作Loading详解(来自我的长微博)》有 16 条评论

  1. lizhi 说:

    雨松么么,为什么要通过增加场景数来减少动态加载。不是应该是减少场景数,多用动态家在吗

  2. 艾欧 说:

    雨松大大,我为什么我得到的进度值不是0就是1呢~都没有中间的插值~

  3. 新的 说:

    大神,发布成web版,如何在打开html 的时候显示加载资源的百分比啊?跪求指导

  4. maxyoo 说:

    请问怎么把新场景导入到一个设置了DontDestroyOnLoad了gameObject里呢

  5. Barbarian 说:

    怎么觉得LoadLevelAsync跟LoadLevel没多大区别呢,基本开始加载就卡住了,Update都停了

  6. FG911 说:

    没有真正的多线程加载是硬伤,哎

    • 逍遥随风翼 说:

      你直接建立一个空对象,然后把异步处理写成脚本绑上不就是多线程了吗??Unity里的每个继承Monoh的脚本其实本身就是一个线程。

      • FG911 说:

        thread 和 coroutine 可不是一个东西,麻烦先搞清楚这个概念,unity所有对context操作的接口是不允许在其他线程环境下工作不信你new thread然后loading试试

  7. 七喜 说:

    我就是这么做的,效果还不错, 如果有些大的 perfab太大 导致了进度在进度条上卡的时间长的话 可以把那个大的perfab 拆开来 拆成两个小的 ,调整一下,进度条就均匀了

  8. 自由之翼 说:

    Mo大侠,很感谢你分享这么多干货。我有个问题,如果只做一个Unity场景,逻辑场景(用配置定义的场景)使用协程加载,每加载一个GameObject更新一次Load界面进度条,这样有什么问题?进度会很不均匀吗?

留下一个回复

你的email不会被公开。