Unity技术分享(66)| AssetBundle资源冗余 | TraceShape耗时...

原文链接:
https://blog.uwa4d.com/archives/TechSharing_66.html

我们将从日常技术交流中精选若干个开发相关的问题,建议阅读时间15分钟,认真读完必有收获。如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。
UWA QQ群:465082844
UWA 问答社区:answer.uwa4d.com


资源管理

Q1:我在Unity 5.5.2下用AssetBundle依赖打包,但是LoadAllAssets之后,内存中却存在两份相同的文件。

打包过程如下: 将资源A(material)打包到testmaterial.bundle,然后将纹理B打包到testtexture.bundle,再使用一个Sprite C引用纹理B后,将Spirite生成一个Prefab并将其打包到testprefab.bundle。最后导出成的3个Assetbundle之间的依赖关系为:A(testmaterial.bundle)依赖 B(testtexture.bundle),C(testprefab.bundle)依赖B(testtexture.bundle),从最后的生成的manifest也可以看出来依赖关系跟预期的一致。

Unity技术分享(66)| AssetBundle资源冗余 | TraceShape耗时..._第1张图片

Unity技术分享(66)| AssetBundle资源冗余 | TraceShape耗时..._第2张图片

测试内存:
我们分别将这个3个AB使用相同的方式在一个空工程中做测试,代码如下:

Unity技术分享(66)| AssetBundle资源冗余 | TraceShape耗时..._第3张图片

然后在Profile查看内存得到的结果,很明显在内存里面测试的纹理存在两份,这是为什么呢?

Unity技术分享(66)| AssetBundle资源冗余 | TraceShape耗时..._第4张图片

我们按照提问者的步骤做了下测试,确实在Unity 5.5.2版本中复现了这个问题,可见下图,mat对应了testmaterial.bundle,texture对应了testtexture.bundle,sprite对应了testprefab.bundle。可见纹理会出现在mat和texture两个bundle中,且mat也不再依赖于texture(这与manifest中的记录不符,所以暂估计是Unity的Bug)。


Unity技术分享(66)| AssetBundle资源冗余 | TraceShape耗时..._第5张图片

但在Unity 5.3.5中用同样的方式打包是没问题的,结果见下图:


Unity技术分享(66)| AssetBundle资源冗余 | TraceShape耗时..._第6张图片

总之,Unity 5.5系列中这种用法确实需要注意了,目前暂时只能通过把mat和texture合并在一个包里来解决。

另外,感谢UWA 问答社区的钱康来补充了以下内容:
我们在使用Unity 5.4的时候,也遇到这个问题,经过反复测试后发现:如果一个贴图一方面被当成Sprite使用,另一方面被当成Texture使用(譬如RawImage或者Material),就会断开引用产生多份。目前解决办法是保证用Sprite的Prefab及Material打包在一个AssetBundle。

此问答来自于UWA 问答社区:
https://answer.uwa4d.com/question/5927c74052f250573aa862d9
如您对该问题仍有疑问,可以转至社区进行进一步交流。


UGUI 字体

Q2:Unity 5.5版本下的UGUI,我将字体设置为粗体,发现字体只是变宽不加粗,不像正常的粗体,如下图所示。另外,TestMesh Pro需要预渲染,不能用动态字体,只能用于特定范围,有像NGUI(效果还不错)那种对动态字体加粗的方法么?

Unity技术分享(66)| AssetBundle资源冗余 | TraceShape耗时..._第7张图片

动态字体加粗显示的外观是和字体本身有关系的,如果字体中没有包含“粗体”的字形,那么Unity会通过拉伸来“模拟”加粗,因此得到的效果是有问题的。而这个行为在UGUI和NGUI中是一样的。因此,如果要确保加粗显示正确,则需要使用包含了“粗体”字形的字体,甚至需要考虑是否将其include到发布包中(因为某些设备中的内置字体也有可能被精简过)。


性能优化

Q3:这个红框里面的内存是如何生存的?是实例化生成的吗?但为什么GameObject被销毁掉之后,这部分内存也不会被释放呢?

Unity技术分享(66)| AssetBundle资源冗余 | TraceShape耗时..._第8张图片

图中的MonoBehaviour也包含了被加载出来的Prefab上的组件(通过Load接口加载出来的),而这部分组件只能在Prefab被销毁的时候才会释放。


UGUI

Q4:请问UGUI Image 在切换Sprite(网络图片) 的时候有卡顿,从Profiler中看到具体卡在SpriteMeshGenerator.TraceShape 这个方法上,如下图所示,有没有什么优化的方法呢?

图中的SpriteMeshGenerator.TraceShape/Decompose/Simplify的函数,通常出现在加载或者创建(Sprite.Create)SpriteMeshType为Tight类型的Sprite时,Tight类型的Sprite在加载或创建时,需要检测图片的alpha区域从而生成多边形。计算量较大,建议将其改为FullRect模式。


性能优化

Q5:New出来的Mesh好像都是可读写的,在我填充完数据以后,有什么办法能把这个Mesh改为只读么?

通过 new Mesh创建的网格可以通过以下接口变为只读的,从而降低一部分的内存占用:
https://docs.unity3d.com/ScriptReference/Mesh.UploadMeshData.html


今天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题也许都只是冰山一角,我们早已在UWA问答网站(answer.uwa4d.com)上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入,也许你的方法恰能解别人的燃眉之急;而他山之“石”,也能攻你之“玉”。

官网:www.uwa4d.com
官方技术博客:blog.uwa4d.com
官方问答社区:answer.uwa4d.com
官方技术QQ群:465082844(仅限技术交流)

你可能感兴趣的:(Unity技术分享(66)| AssetBundle资源冗余 | TraceShape耗时...)