1)运用Post Processing导致帧率明显下降
2)RectMask2D是不是会频繁触发SendWillRenderCanvases
3)Unity3D Sence为何一直处于已修改状态
4)Sprite Atlas打Bundle的冗余问题
5)IL2CPP在Xcode下增量编译问题
这是第220篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题,建议阅读时间10分钟,认真读完必有收获。
UWA 问答社区:answer.uwa4d.com
UWA QQ群2:793972859(原群已满员)
Rendering
Q:项目中运用了Post Processing后,帧率下降巨大。测试场景,模型面数2w,普通的Diffuse材质 ,没有物理,没有特效。没开后处理时,低端机30帧。开启后处理,帧率抖动,最低达到15帧。后面只用到Bloom和Color Grading。
A:如果Bloom用的不好,GPU性能耗时高是较为正常的事情。Bloom的上下采样次数、Filter滤波的Sample点个数、屏幕的分辨率等都是影响Bloom性能的重要因素。建议题主可以考虑阅读《Unity引擎景深实现原理剖析与优化》这篇技术课程,里面优化DOF的方法依然可以用到Bloom上。
同时,也可以使用GOT Online中的Overview模式,直接查看项目在真机上(最好是高通芯片)的GPU耗时,看看GPU的具体超标情况:
该回答由UWA提供
UGUI
Q:RectMask2D是不是会频繁触发SendWillRenderCanvases?
A:是的,Rect Mask 2D会持续每帧计算子节点的裁剪区域。所以Rect Mask 2D下面的元素如果比较多,耗时还是挺高的,这种情况可以换成Mask组件,虽然Mask的Overdraw会高一些。一个省GPU,一个省CPU,两个是需要权衡的。
感谢Xuan@UWA问答社区提供了回答
Editor
Q:Unity 3D Sence一直处于已修改状态。刚切换过来也直接提示已修改。切换Sence并未作出任何修改,如下图:
虽然没什么难题,但切换别的场景或者退出的时候就要提示让保存了。
之前发现的一个原因是因为UI中存在套用的Layout组件呈警告状态。修改后Sence就恢复正常了。各位有遇到过这种问题吗?
A:所以说还是嵌套了Layout组件。这个会导致Sence一直处于修改状态。
感谢刘旭杰@UWA问答社区提供了回答
AssetBundle
Q:游戏中UI用Sprite Atlas做合图,打Bundle貌似碰到了一个冗余问题:(Unity 2019.4.1 lts版本)。
Victory目录有四张散图,以及一个Sprite Atlas文件做合图。Bundle时把整个Victory为一个Bundle。最终出来的Bundle结构如下:
也在网上搜了一些信息,尝试去掉Sprite Atlas的Include in build选项(效果未验证,纯粹验证Bundle),Bundle中少了一份冗余的Texture 2D,但依旧有几个Sprite类型的散图。
疑问:
我理解是,Bundle中已经有一个sactx-1024x2048的合图了,为什么还有Sprite类型的散图?这是否算冗余呢?
用去掉Include in build的方式,游戏中使用UI Prefab时,是否都需要用Late Binding才能使用图片(感觉很麻烦,UI拼每个界面,都要程序写配套代码)?
A1:最开始描述的问题中(根据第一张截图)并未看到冗余的存在,也并非图集形式的打包结果。回答如下:
对于图集本身的Bundle肯定是不算的,需要有各个散图的信息才能从整图中获取散图,不然就不知道你要的那个图在哪里。不勾选Include in build,Bundle中就不会存在显式的图集依赖,必须使用延迟绑定传递信息(该图片从哪个图集中获取)给请求图片资源的对象。
感谢Welkin_Totoro@UWA问答社区提供了回答
A2:描述下我的思路:勾选了Include in build,Bundle中就会有一份冗余:既包含合图,又包含散图。但这种情况下,程序不需要做特殊逻辑,界面就能表现正常(具体Runtime是否合图,未抓帧验证)。
不勾选Include in build(正确做法):Bundle就会只包含Atlas,以及散图信息(不是完整的散图)。游戏内使用Atlas Request Manager来确保图片能正常显示,否则会错乱。如果自己实现了资源加载的话,可能还要自己找时机做Atlas资源卸载。
感谢james@UWA问答社区提供了回答
Build
Q:最近在研究加速打包问题,发现IL2CPP生成代码之后每次Xcode都是全量编译(直接Build而不是Clean+Archive)。
我参考这里看了下,
https://forum.unity.com/threa...,
对比了下如果C#代码没有变化,生成的CPP代码的内容确实不变。但是重新生成貌似会导致文件修改时间变化或别的属性变化,Xcode依然是所有都编译了一遍。
A1:目前准备用群里大佬说的方法绕开:
“Freshair 17:01:28 打出的Xcode用SVN同步到Xcode打包项目下”我用Dnspy看了下IL2CPP.exe直接修改代价有点大,而且不好维护。用BeyondCompare比较了下发现其实就Preprocessor.h和Native文件夹俩修改时间产生了变化。希望以后官方能注意这些细节。
感谢钱康来@UWA问答社区提供了回答
A2:介绍一篇文章 《Unity Xcode构建缓存》,里面写了一个程序解决Unity生成Xcode项目缓存问题。WriteCache使用Rsync增量传输,会节省时间,ReadCache未做优化,实测用时37秒左右,1.5GiB大小Xcode项目——UnityXcodeCache
感谢狂飙@UWA问答社区提供了回答
A3:我之前的做法是细化打包策略,资源打包细分为差不多10个步骤,对 UI,特效,Lua(分三块,Core,模块,Luatable配置),C#层Config,角色,场景,编译工程,资源覆盖,快速编译,生成APK/IPA,云真机测试,组织成不同的打包命令提供给CI。如果是C#代码没变化,可以只做资源类的打包,对需要重新(此处可增量)打包的AssetBundle,Lua,Config等打包,打包后直接覆盖到Xcode工程,直接生成IPA包,跳过中间环节,构建过程可以细化到很细,如果你是Lua侧,那估计只需要打包Lua模块相关,1分钟内就可以出到IPA包。
如果是Xcode代码也发生变化,这个可以结合Ccache进行提速,资源打包可以做分布式打包,多台黑苹果去打包各个模块的资源。再传递到版本机上整合,这个过程也可以hook svn/git的资源提交,在提交后做一次打包,再次发布的时候可以增量处理。
其实可以脱离AssetBundle,把量产资源采用非AssetBundle的方式进行组织。避开不必要的导入导出及打包。
感谢debugger@UWA问答社区提供了回答
封面图来源于网络
今天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题也许都只是冰山一角,我们早已在UWA问答网站上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入,也许你的方法恰能解别人的燃眉之急;而他山之“石”,也能攻你之“玉”。
官方技术QQ群:793972859(原群已满员)