技术分享连载(六十九)
- 作者:admin
- /
- 时间:2017年06月27日
- /
- 浏览:4445 次
- /
- 分类:厚积薄发
本期我们聚集了这些话题:被自动打进AssetBundle的资源无法主动加载出来吗、Spritepacker自动划分Group、资源Ref count为空、Graphics ApI选择...
我们将从日常技术交流中精选若干个开发相关的问题,建议阅读时间15分钟,认真读完必有收获。如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。
UWA QQ群:793972859
UWA 问答社区:answer.uwa4d.com
资源管理
Q1: 在打包的时候,有一部分资源是没有设置AssetBundleName的,打包的时候会和依赖它们的资源打到同一个AssetBundle包里(Unity自动完成)。在资源加载的时候,无法主动获取到这些没有设置AssetBundleName的资源。GetAllAssetNames、LoadAllAssets这些接口的返回值中都没有这部分资源。
请问,在你们看来,这种情况是Unity的设计还是Bug?如果是如此设计的话,有什么特别的意义吗? 提供一个简单的情景,如下:
1)有A、B两个Prefab,其中A上挂个脚本引用了B
2)打包的时候,设置A的AssetBundleName="prefab.unity3d",B的AssetBundleName=None
3)打包,只产生prefab.unity3d这一个AB包,其中包含了A、B两个资源
4)加载代码使用AssetBundle.LoadAllAssets(),返回的数组里只有一个资源(A)
我们刚刚在Unity 5.5.2版本上进行了一个测试,得到与题主一样的结论。
我们更加倾向于它是一种设计,而非Bug。因为Prefab B是作为一种参数被引用在A的脚本中,所以在AssetBundle中,它将以GameObject B的形式存在,但是不会存在于AssetBundle的映射表中。而对于题主的这种打包方式而言,AssetBundle的映射表中只会有一个,就是Prefab A。而AssetBundle.LoadAllAssets虽然会把GameObject A、B及其关联的资源全部加载,但其返回的Object[]内容应该就只有一个,也就是Prefab A。 所以,UWA推测,AssetBundle中在打包时是自己维护了一个map的,只有明确被设置ABName的资源才会被放入map中,也只有map中的资源才可以通过特定名称进行Load,而其关联的资源则会被打包到AssetBundle中的其他container中,是无法通过LoadAsset或LoadAllAssets API来获取到的。
此问答来自于UWA 问答社区:
https://answer.uwa4d.com/question/594dc62dba16a4c31f8ca1ac
如您对该问题仍有疑问,可以转至社区进行进一步交流。
性能
Q2:UGUI自动打包图集时,有时候同一个Tag会自己打出多个Group图集,导致DrawCall增加,有什么解决方法吗?这个分Group的原理是什么?
不少的项目都会遇到这个问题,即很多纹理打上了相同的Tag,但是却出现在了不同的Group中,类似下图,一个图集里包含了四个Group:
而产生Group的原因主要有两种:1. 纹理的格式不同 。举例来说,有这样四张纹理格式分别为:RGB24,ETC1,RGBA32和ETC2,那么设置一样的Tag后,对应的图集就会有四个Group:
2. 纹理量太大。一个Group放不进,这个原因是容易理解的,就不解释了。
其中特别容易忽略的一点是,某些小纹理可能没有Alpha通道,导致了图集被分成两个Group,引起DrawCall的增高,这种情况下可以直接修改纹理,也可以强制设定为Aalpha通道的格式。
此问答来自于UWA 问答社区:
https://answer.uwa4d.com/question/594cef012a0bce361ae401ba
如您对该问题仍有疑问,可以转至社区进行进一步交流。
性能
Q3:Gfx.ProcessCommands包含哪些行为操作?据我了解,该行为是在RenderThread中,导致该行为耗时的主要原因是DrawCall。 那么除了DrawCall还有那些行为被记录到该过程中呢? 另外这过程耗时统计是否还包括顶点、材质贴图以及Shader等从内存到GPU的IO时间呢? 该问题限制在OpenGL ES 2.0/3.0驱动下思考,无需考虑Vulcan/Metal等目前面向多线程的驱动。
题主所列的这些行为应该是都在里面的。因为,即使是多线程渲染,图形API的调用也需要在同一个线程中。其一,是Android系统的EGLContext一般不是线程独共享的,也就是只有一个线程能向同一个EGLContext里面发送GL指令。其二,如果使用共享的EGLContext,多个线程都能提交图形API,渲染的结果很难保证正确性。比如:如何保证线程A绑定了VBO或者Texture之后,线程B提交DrawCall时一定是它需要的呢。综上所述,我们认为这些行为应该都在一个线程里面执行的。
此问答来自于UWA 问答社区:
https://answer.uwa4d.com/question/594a1e2b8a2462602c976405
如您对该问题仍有疑问,可以转至社区进行进一步交流。
性能
Q4:大家现在在工程里还是选择只使用 OpenGL ES 2.0吗?我记得以前大家都是这么做的,现在这个做法过时了吗?iOS 是否该加上 Metal?
我们目前都是用的Auto,主要有两个原因:
- Metal测试下来CPU Overhead会比GLES低很多
- GLES3能够有tex2Dlod支持 兼容性上来说只有实在老的机器和模拟器会fallback到GLES2,可能效果上会略差一些不过我们测试下来都可以接受。
感谢 UWA 问答社区的钱康来提供了以上回答。
我们现在快要上线的项目选的是ES3.0,iOS和Android都是选的这个,iOS选Metal的时候遇到模型显示不正常的问题,但是能力有限加上没时间没定位到原因,就统一成ES3.0了。选ES3.0还有一个原因,就是发现AssetBundle打出来的资源会比选Auto小很多。 还有就是目前我们的游戏偏重度,不指望用老手机的玩家会付费,所以放弃显卡太老的机型了。
感谢 UWA 问答社区的李先生提供了以上回答。
此问答来自于UWA 问答社区:
https://answer.uwa4d.com/question/594ddec949dc1fb06ce0685f
如您对该问题仍有疑问,可以转至社区进行进一步交流。
性能
Q5:Unity Profile性能检测中,请问Ref count什么情况下可以为空?
这说明当前fabao_suipian这个资源没有被任何脚本、资源所引用。如果之前该资源有引用,那么现在引用它的资源应该被销毁了。
比如,这个Texture之前可能被Material所引用,那么现在这个Material应该被UnloadAsset释放了。 再比如,这个资源是题主通过Resource.Load或AssetBundle.Load来加载的,然后将其缓存在一个变量中,那么当该变量被设置为null时,也会资源不再引用的情况。 所以,题主需要根据自己的情况来判断一下,这个资源是哪里加载的,具体想怎么使用。
此问答来自于UWA 问答社区:
https://answer.uwa4d.com/question/594e15ecf27d373e23a1a09e
如您对该问题仍有疑问,可以转至社区进行进一步交流。
今天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题也许都只是冰山一角,我们早已在UWA问答网站(answer.uwa4d.com)上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入,也许你的方法恰能解别人的燃眉之急;而他山之“石”,也能攻你之“玉”。
官网:www.uwa4d.com
官方技术博客:blog.uwa4d.com
官方问答社区:answer.uwa4d.com
官方技术QQ群:793972859(仅限技术交流)