原文链接:https://blog.uwa4d.com/archives/TechSharing_58.html
我们将从日常技术交流中精选5个开发相关的问题,建议阅读时间15分钟,认真读完必有收获。如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。
UWA QQ群:465082844
UWA 问答社区:answer.uwa4d.com
粒子系统
Q1:我们项目中有大量的特效,一个特效Prefab可能包含100-200个GameObject,每个GameObject上都挂有一个粒子系统,但是实际上很多特效只有延时和坐标旋转之类的参数的区别。我看了Prefab文件后发现每个粒子系统分别记录了各自的信息,从而导致整体文件很大,内存占用也比较大。请问是否有优化的方法?
如果开发的是一个手游项目,那么一个Prefab下含有100-200个粒子系统是非常不足取的,主要会造成以下几种问题:
同时播放100个以上的ParticleSystem,其ParticleSystem.Update本身的CPU占用会很高。下图为一款游戏在华为6Plus上的表现。可以看到Active Particle数量还没有达到100,其Update耗时就已经占到了5ms;
ParticleSystem.ScheduleGeometryJobs开销会很高。其耗时主要体现在渲染模块中的Culling阶段,与粒子系统的数量相关,场景中Active粒子系统的数量越多,其开销越高;
子线程中的渲染压力较大。Unity5.3版本以后,粒子系统的渲染虽然在主线程中占用很小,但并不意味它没有耗时,其耗时在渲染线程中,当渲染线程压力过大时,主线程同样会出现等待(Gfx.WaitForPresent),因此同样可能对帧率产生影响;
GPU的渲染压力较高。同屏中渲染的粒子系统越多,其屏幕每帧的填充率越高,从而更加容易造成设备的发热;
内存压力较高。如果一个Prefab上有100-200个粒子系统,并且如果场景中有10个以上这样的Prefab存在,那么其内存占用将在10~25MB内存区间内。就目前而言,粒子系统仍然是以Clone的形式存在,所以虽然粒子系统可能仅仅是某些参数不同,但其仍然是多个不同的粒子系统。因此,我们在UWA报告中会显示粒子系统在项目运行时的具体显示数量,以方便研发团队对粒子系统进行关注。如下图所示,一般来说,每帧中粒子系统的数量建议在400以下。
综上所述,就目前的硬件环境来看,如果是研发一款手游项目,那么一个特效中包含100~200个粒子系统是非常不合适的。当然,如果是PC项目,那么就另当别论了。我们目前并没有针对PC项目进行过深入研究,欢迎其他PC端开发的朋友来进行分享。
此问答来自于UWA 问答社区:
https://answer.uwa4d.com/question/58ddedeb0d9eacab7dc86653
如您对该问题仍有疑问,可以转至社区进行进一步提问。
NGUI
Q2:我们游戏中用到NGUI的HUD,单位主要是一个进度条和一个倒计时文本(持续更新),同屏数量达600左右,单位本身在持续移动。现已将这些设置为独立Panel,且只有2个DrawCall(进度条所在图集和文本),但还是卡顿得很厉害,请问是否有优化的方法?
同屏600的数量确实已经非常高,目前该使用方式的瓶颈在于网格更新和合并开销,建议研发团队先从以下几个点进行优化:
简化元素的几何:进度条中的元素尽量避免Sliced 模式(改Simple);倒计时部分如果使用了Outline或者Shadow,将其转为“图片字”;
降低更新频率:如倒计时按“秒”统一更新;进度条按1%甚至5%的间隔更新一次;移动速度较慢时可以尝试隔帧更新位置等;
拆分子UIPanel:尽可能将更新频率相同的UI元素放在一个UIPanel中,从而降低每次更新时涉及到的UI元素数量。具体的拆分数量,则可能要通过较多的测试来确定。需要说明的是,此处即使增加10到20个DrawCall,对渲染上的影响并不大。
此问答来自于UWA 问答社区:
https://answer.uwa4d.com/question/58dd38884e69b5ed22e68ada
如您对该问题仍有疑问,可以转至社区进行进一步提问。
动画系统
Q3:如下图,请问这几个参数的单位是什么?
Rotation Error使用角度(degree)作为单位。Position和Scale是距离偏差的百分比(曲线调节前后的距离偏差与某距离值之比,取决于Unity内部实现),取值范围1~100,但实际可以高于100,并有作用。
我们建议研发团队在调节该误差时,将调节前后的动画效果进行对比,使文件体积压缩得尽量小,同时使动画效果在视觉上偏差不会太大。
动画系统
Q4:如下图,这个ResampleCurves选项的作用,以及是否和对内存性能的影响?
该问题来自UWA问答社区,如您对该问题仍有疑问,可以转至社区进行进一步交流。 https://answer.uwa4d.com/question/58e4aa2b69c2b4c705f84e64ResampleCurves选项是在Unity 5.3版本后加入的,在之前的版本中是隐藏并且默认勾选的。该选项会改变Unity动画数据的存储方式。动画文件在导入到Unity之前,其关键帧的数据通常是以欧拉角(Euler format)的方式存储。在勾选该选项时导入,Unity会将欧拉角转换为四元数(Quaternion)表示,并且会生成逐帧的数据(不只是关键帧)。新生成的逐帧数据是为了解决四元数插值问题。关闭该选项会使动画文件保持欧拉角表示,但在应用于GameObject时仍会转换为四元数。
我们建议保持默认勾选该选项,只有当发现Unity中的动画播放效果与在动画编辑工具中的效果出现较大偏差时,尝试取消该选项,查看是否是该选项的原因导致动画偏差。我们在测试中发现该选项对运行性能影响并不明显。在内存方面,勾选该选项会使动画文件略微增加。
资源管理
Q5:我们美术作的人物动画,是不需要用到缩放的,于是我做了一个Scale Curve剔除。对比运行时数据如下:
剔除前:
剔除后:
可以看到Curves Count减少了很多,效果应该是有的,但是与此同时,我在编辑器里看这个Clip的内存占用反而相比剔除前增大了150%(之前是0.6MB,现在是1.5MB)。我反复测试,这个数据很准确,这是为什么呢?
附Scale曲线剔除的代码:
UWA使用研发团队提供的两个动画文件进行真机测试,结果如下:
- 对于动画guanyu_anim, 去除Scale前内存占用9.8M,去除Scale后内存占用9.8M;
- 对于动画suishi_taluo_anim,去除Scale前内存占用197.6K, 去除Scale后内存占用174.5K。
UWA并未复现问题中所述的内存增加的现象。在此,我们建议研发团队先确认下,截图是直接获取的数据(即Editor下的内存占用)还是连接了真机的内存数据。(注意:在Profiler中获取的Editor下的内存数据并不是在真机上的实际内存数据,并且相差较多。因此建议连接真机后再测一下,看看是否仍然内存增加。)
同时,研发团队如果想在Editor中了解动画文件在真机内存中的占用,可以看Inspector里显示的容量,该数据与真机内存占用非常接近(虽然并不完全相同):
今天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题也许都只是冰山一角,我们早已在UWA问答网站(answer.uwa4d.com)上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入,也许你的方法恰能解别人的燃眉之急;而他山之“石”,也能攻你之“玉”。
官网:www.uwa4d.com
官方技术博客:blog.uwa4d.com
官方问答社区:answer.uwa4d.com
官方技术QQ群:465082844(非水群,仅限技术交流)