Q&A——资源管理(四)

资源管理

Q1:Unity 5.x 能把指定集合的Mesh烘焙到一张Lightmap里吗?

Unity 5.x 是没有这样的功能项的。据我们的判断,这样的需求通常是为了动态加载,因此可以尝试将Mesh分组到不同的场景分别烘焙。而在加载时可通过脚本动态地合并Lightmap,同时将物件的Lightmap Index进行正确的偏移即可。

资源管理

Q2:请问一下,我两个预设都引用了第三个AssetBundle的贴图,如果不希望这张贴图存在两份,一定要等这两个预设都加载好了,才能卸载贴图的AssetBundle吗 ?

是的,但并不是因为这样做会使“这张贴图存在两份”,而是因为如果先卸载贴图的AssetBundle会导致后续加载两个预设时会丢失依赖,即找不到贴图。如果脚本中会对这个情况进行检查并重新加载贴图的AssetBundle,那么此时才会造成“这张贴图存在两份”的问题。


资源管理

Q3: 关于Loading.ReadObject耗费比较高,有什么推荐的方法吗?

Loading.ReadObject是Unity引擎的资源加载函数,一般出现在切换场景和加载API调用时,这其中包括纹理、网格、Material、Shader、AnimationClip等资源。如果你发现该值过高,建议去大力优化加载的相关资源。对于每种资源的加载,我们正在以专题的方式进行总结和分享,建议大家可以先查看以下内容:
加载模块之纹理
加载模块之网格
加载模块之Shader

资源管理

Q4:请问音频中的 Quality 什么意思?一般设置为多少合适?我拖进去一首歌曲,试了一下 在0 和 100 的情况下区别不大,但是生成的音频文件大小差别很大。

UWA Tech Doc

Quality 表示在压缩音频时的失真程度(实际上可以认为是压缩算法的一个参数),该值越大,压缩后的文件越大,但音质保留的越好。而对于其失真的程度是视音频数据以及内部的压缩算法而定的,确实会有区别不大的情况。该值的设置原则就是,在音质失真可接受的情况下,越小越好。


资源管理

Q5: 我做的预设用到了这个字体

UWA Tech Doc
我将这个预设打成AssetBundle包,通过Profiler分析时发现占了两份内存。

UWA Tech Doc
下面这个SIMHEI应该是那个TTF的,为什么会占两份内存呢?

通常TTF文件会包含一个字体的多个字型,如可能包含正常字型、加粗字型、斜体字型等。而在Unity中会将其分为不同的Font资源,且他们之间会相互依赖。所以,如果项目中确实需要加粗字型的话,内存里出现两个Font是正常的,但如果实际上不需要加粗,那么可以尝试寻找一个不包含加粗字型的字体文件来替换该TTF文件。


资源管理

Q6: 我在Profiler中看到GameObject.Deactivate耗时较大,请问该如何优化?

实际上GameObject.Activate/Deactivate本身通常不会产生很高的开销,主要都是由其上或其子节点上的组件的OnEnable/OnDisable操作引起,比如UI相关的组件在OnEnable和OnDisable中都会有较多的操作,所以较复杂的UI界面的GameObject.Activate/Deactivate会有很高的开销。因此,针对这一问题,如果是由自定义的脚本造成,那么就需要考虑优化OnEnable/OnDisable的逻辑;如果是UI,那么可以对频繁切换激活状态的UI采用平移出屏幕、修改Culling Layer等方式来替换。


资源管理

Q7: 我有一个特效依赖了两个FBX。我把这两个FBX的这个勾选去掉,Editor运行正常。

UWA Tech Doc
否则就会宕机,请问这是什么原因?

将FBX上的Read/Write Enabled关闭后,内存中便不再保存其Mesh的副本(只存在显存中),因此其属性就不可再被访问和修改。而粒子系统通常需要动态地修改其粒子的顶点属性。因此,理论上来说,供粒子系统使用的Mesh是需要开启Read/Write Enabled的,而在Editor下Mesh和Texture都是强制开启的,所以在真机上就会出现问题。


资源管理

Q8:字体作为多个资源的依赖包,会在游戏中被加载多次。我们现在有个问题,AssetBundle A资源依赖于这个字体,加载A的时候加载了一份字体,然后B资源也依赖这字体,而后加载B的时候我们没有去重复加载字体,这时候发现B资源上出现了字体丢失的现象。

请问加载资源的时候,Unity会自动去识别内存里是否有它的资源依赖包吗?如果有的话,为什么B加载的时候找不到已经存在内存中的字体?这里需要手动去做些什么处理吗?

同时我发现依赖包资源如果进行了bundle.m_AssetBundle.Unload(false)以后,其他依赖于这个包的资源就引用不到了。我们流程上对于每个读进来的AssetBundle,都会加载完后马上进行Unload(false),请问如果是依赖包的话,是不是不能对其进行这步操作?

Unity引擎是会自动根据依赖关系去搜寻依赖的资源的,但需要注意的是,依赖的AssetBundle文件必须存在。也就是说,依赖关系包如果后续还会使用的话,是不应该被Unload的,否则后续AssetBundle加载上来后,被依赖的资源是无法找到的。对于Unity 5.3之前的版本,出于内存的考虑,开发团队可以通过CreateFromFile或LoadFromCacheorDownload来加载AssetBundle,既可以保留AssetBundle之间的依赖关系,同时又不会产生Webstream。

开发团队可以参考你应该了解的AssetBundle管理机制,进一步了解相关API。

资源管理

Q9:SkinnedMeshRenderer.BakeMesh这个函数一般是什么时候调用呢?在Instantiate后调用么?

SkinnedMeshRenderer.BakeMesh 的作用在于:将一个蒙皮动画的某个时间点上的动作,Bake成一个不带蒙皮的Mesh,从而可以通过自定义的采样间隔,将一段动画转成一组Mesh序列帧。而后在播放动画时只需选择最近的采样点(即一个Mesh)进行赋值即可,从而省去了骨骼更新与蒙皮计算的时间。

该方法的优点是用内存换计算时间,在场景中大量出现同一个带动画的模型时,效果会非常明显。该方法的缺点是内存的占用极大地受到模型顶点数、动画总时长及采样间隔的限制。因此,该方法只适用于顶点数较少,且动画总时长较短的模型。同时,Bake的时间较长,因此需要在加载场景时完成。

比较经典的适用场景为MOBA游戏中的小兵。

资源管理

Q10:将Shader独立打包,如果我在启动游戏的时候加载一次,那么之后切换场景是不是就不用每次都加载了?

确切地说,要达到后续Shader都不出现加载开销,需要满足以下两个条件:
(1)包含Shader的AssetBundle文件常驻内存;
(2)Shader已经全Load加载好;

只要满足这两个条件,后续加载好的GameObject,但凡依赖于这些Shader的,都会直接拿来进行使用,而不会再有加载和解析开销。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值