异步加载场景与异步加载游戏资源

异步加载场景与异步加载游戏资源

Application.LoadLevel 加载关卡

在同步加载游戏场景的时候通常会使用方法Application.LoadLevel 加载关卡。
该方法在执行完Application.LoadLevel方法后,会把该场景在 Hierarchy 视图中的所有游戏对象加载至内存当中。因为Application.LoadLevel,若是场景内游戏对象过多,则会在加载的瞬间卡顿一下。

因为 LoadLevel()方法是同步进行的。

Object.Instantiate 实例化

C# => static Object Instantiate(Object original, Vector3 position, Quaternion rotation);
C# => static Object Instantiate(Object original);
克隆原始物体,位置设置在position,设置旋转在rotation,返回的是克隆后的物体。这实际上在Unity和使用复制(ctrl+D)命令是一样的,并移动到指定的位置。如果一个游戏物体,组件或脚本实例被传入,实例将克隆整个游戏物体层次,以及所有子对象也会被克隆。所有游戏物体被激活。

Instantiate通过脚本动态的创建出来的游戏对象的,属于后天加载。

异步加载游戏场景

异步加载的方式分为两种:
第一种:加载新游戏场景,当新场景加载完成后进入新场景并且销毁旧场景。

Application.LoadLevelAsync 异步加载关卡

第二种:新场景加载完毕后,保留旧场景的游戏对象并且进入新场景。

Application.LoadLevelAdditiveAsync 异步累加关卡

异步加载的游戏 LOADING 界面

例如从场景1进入场景2,可以建立一个过渡的LOADING场景,先从场景1读取LOADING场景,当异步加载完成后再从LOADING场景进入场景2。因为LOADING场景仅仅只是绘制进度条或过渡动画,所以该场景的加载应该是瞬间就可以完成的。

这个方法需要使用MonoBehaviour.StartCoroutine 开始协同程序
MonoBehaviour.StartCoroutine 开始协同程序

注意:
AsyncOperation.progress 进度
C# => float progress;
Description 描述
What’s the operation’s progress (Read Only)
操作的进度是多少?(只读)
progress 的取值范围在 0.1-1 之间,但是它不会等于 1,也就是说 progress 可能是 0.8 或者 0.9 的时候就直接进入新场景了

AsyncOperation.isDone 是否完成
JavaScript => var isDone: bool;
C# => bool isDone;
Description 描述
Has the operation finished? (Read Only)
有操作完成了吗?(只读)

在游戏场景中加载对象

在 Hierarchy 视图中设置游戏对象的active为false,可以让游戏对象不会在切换场景时被加载。
当需要加载大型场景时,可以先把场景内的游戏对象的active全部设置为false,然后在场景加载完成时开启一个协同程序一个一个加载显示出来。

编辑器赋值与代码中赋值的区别

编辑器中赋值所消耗的时间都会记在 loadlevel()读取场景中。

代码中使用Resource.load()这类方法所消耗的时间会记在脚本中。

而使用 Instantiate();方法来动态的创建游戏对象没有什么时间上的消耗的,一般都会在1毫秒内就能完成。有一些特殊的模型会消耗一定的时间,但很少见,比如某些UGUI的UI模型比较复杂,在生成的时候会花费一定的时间。

问题:Thread 可以代替StartCoroutine()吗

答案是不行,比如查询数据库的时候如果用 Thread 的话 Unity 就会报错说不能在线程中查询,但是在 StartCoroutine()
中就可以完成,所以开发中大家可以尝试着使用它,我们还可以使用 StopCoroutine(“name”)来关闭一个正在执行的异步线程。

本文固定链接: https://www.xuanyusong.com/archives/1427
转载请注明: 雨松MOMO 2012年07月01日 于 雨松MOMO程序研究院 发表

Unity 关于资源加载的时间消耗

(转自:http://www.taidous.com/forum.php?mod=viewthread&tid=42773&extra=page%3D1&page=1)
一般来说把一个预设物体生成在场景里面需要这么几个步骤:

  1. 加载文件,如果是内部Resource文件就不需要加载文件,但AssetBundle是需要先加载某个文件,再转成AssetBundle的。
  2. 读取资源,可能是Resource.Load,或者是AssetBundle.LoadAsset,把资源读成Object
  3. 生成模型,一般是使用GameObject.Instantiate方法把Object生成为GameObject

测试结果出来了,可以分析一下问题的所在:

不难看出,基本的时间消耗都在读取资源那一步。而且读取单一的文件,会比同一个文件拆分多个依赖读取需要的时间短。这里我们可以得出一些结论:

  1. 读取完的资源尽量保存起来,下次再请求读取的时候就可以直接返回结果。
  2. 再次说明了资源的依赖不要拆得太散,能不拆尽量不拆,不然虽然在容量上占优势了,但加载的时候卡,也是得不偿失的。
  3. 由于读取大文件的时间还是长,以30fps算,一帧也才33毫秒的时间,并不能处理很多读取资源的业务。所以可以考虑异步读取资源或者提前读取资源,然后保存起来备用。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值