技术分享连载(六十八)

技术分享连载(六十八)

本期我们聚集了这些话题:如何确定美术规范、DrawCall数量的控制、CPU中高占用函数分析、Profiler.FinalizeAndSendFrame...


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


性能

Q1:Unity Profiler中如下函数的耗时异常高,请问是什么原因导致呢?
1)Profiler.FinalizeAndSendFrame
2)WaitForJobGroup
3)Camera.Render
4)Spine插件中 SkeletonAnimation 和 SkeletonAnimator.Update过高
这些函数分别是什么意思,有什么具体优化方法呢?

请输入图片描述
请输入图片描述

以下是分别对这些函数作出的解释:
(1)Profiler.FinalizeAndSendFrame这个是Unity Profiler在记录和传输性能数据的开销,研发团队可忽略,因为在release版本中,该项并不存在;
(2)WaitForJobGroup这个是主线程在等待子线程完成的耗时开销,如果该项较高,那么说明该帧中某子线程的开销很大。就目前我们优化过的项目而言,绝大部分均为UGUI在子线程的开销所致。更多的参考资料建议研发团队参考UWA问答之前的记录:
https://answer.uwa4d.com/question/search?q=waitingforjob
(3)Camera.Render是Unity引擎的主要渲染函数,其中负责了绝大部分场景的渲染工作,就目前上图的性能截图来看,开销还很低;关于相关参考资源,可以查看以下部分:关于Unity渲染优化,你可能遇到这些问题如何读懂UWA性能报告?—渲染篇
(4)在我个人来看,一方面这个函数在截图中的耗时并不高,另一方面,其耗时主要由调用的次数过高所致,分别调用了25次和156次。这点需要研发团队多多注意。

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


资源管理

Q2:在项目初期,没有任何正式美术资源的情况下,如何给出一个美术资源制作的规范给到美术呢?现在只有一些基本的策划构想,例如:项目定下目标人群、最低兼容手机价位、同屏可见角色数、场景大小、视野范围、角色的面数,角色的贴图数量、角色的骨骼数量、动画数量及时长、场景的面数,场景的贴图数量...

我明白,就上面的策划需求不能得出一个精确的制作规范,只是想要一个大概的推算方式,给出一些大概的参数,好让美术有规范可以参考。不知是否能给些指引?

美术也可以按他们想要的精度先制作部分角色和场景,但只有有限种类的资源的情况下,有方法测算出这个精度在性能允许范围(也就是说这个精度满足策划需求,可以作为美术制作规范)吗?例如只有一个角色(5000面,512贴图三张,80根骨骼),策划同屏要求20个,就在场景中摆20个一样的角色进去(因为只有一个),如果目标手机不崩溃,以后角色的制作就按这样做。这样可以验证这个精度吗?

作为经历了一个新项目在大家都没经验的情况下做出一个刚小范围内测游戏的苦逼开发者,结合群里讨论,个人觉得以下经验可以参考:
(1)选好对标游戏,扒资源来参考。比如畅销榜上的游戏,把资源解出来看,参考模型面数和贴图等游戏。这样最坏的情况下,参考别人能跑上线收到钱的游戏,收钱不保证,但是游戏性能的坑会少很多;
(2)所有口头或文档的规范,都是无效的,不可能得到严格遵守,也就是说,不能用程序检测的规范都是空规范,全部做成Editor菜单检查校验;
(3)用同一个英雄放20份测同屏的方法是不靠谱的;
(4)从gfxbench.com上根据跑分选好基准机型,比如假设要兼容的机型是跑700帧的,那么基准机型得选6000帧的,预留好性能空间,性能别用得太满,否则没回旋余地:
(5)贴图少用RGBA32,让美术在做图的时候,做出来一律以压缩模式的纹理来走Unity导真机包来看效果,千万别只是把美术图导手机相册里看效果,这会和真实的游戏效果有所偏差。建议规范只留两张2048*2048的纹理空间给美术发挥,其余全压缩,否则等美术在高画质模式作出效果后不肯降效果,逼程序优化,性能损耗非常大,程序会万分苦逼。
感谢UWA 问答社区的李先生提供了以上回答。

这确实是个见仁见智并且取决于项目类型的问题,不过题主是在项目初期,想要快速迭代出策划的设计原型,并且要快速制作并且不用与程序产生过多沟通,在此前提下我觉得设定美术规范的首要目的是:不失控。制作出性能优秀的原型不是前期的目的,但毕竟是项目进展的一部分,如果美术资源制作没有标准规范参考,如果随便一个场景都是几十万面,DrawCall超过300,Overdraw可视化都红得发白,那到后面整个团队都要为此付出时间和精力,甚至返工。所以基本的制作规范也是十分必要的。

其次,在项目前期如何看待优化这个问题呢?我觉得过早的优化也是没有太大意义的,谈优化必须首先定位瓶颈,否则盲目优化除了降低资源质量和运算精度,对项目很难起到正面作用。这时项目处于快速变化中,不适合过早断定,所以在这个阶段依然是保证项目即使没有很优秀的性能,但是也没有很严重的问题,这就已经及格了。到了项目后期优化与效果的博弈,这又是另一个话题了。

在以上前提下,假设题主制作的是一个RPG游戏,主城+若干小副本推图,中端手机 iPhone 5,没有程序的太多干预,那么我的建议是:

  • 大致规定好项目在 Unity 中的资源组织格式;
  • 设定好 3dmax 导出模型的比例标尺,最好与 Unity 大小 1:1;
  • 场景总面数均值5-6w左右(大部分),最高10w(少部分),单个模型300-1500面,摄像机可见部分2w以下,导出去除废点,多余的法线(如果没用的话),尽量单面;
  • 场景总面数还要看同屏战斗人数多少做调整,Drawcall最好不超过50,一边给角色和特效留下空间,总 Drawcall 不要超过250这个尽量保证;
  • 场景物体每个模型一个材质球,贴图256为主,正方形,pot(长宽2的倍数);
  • 严格限制场景中透明片的大小和重叠的个数,尽量少用,减少面积;
  • 角色面数部分,主角1500以下;特殊boss2000以下;精英怪物1000面以下;普通怪物800面以下;
  • 每个角色一个材质,除了特殊部件(翅膀等)一律不使用透明材质;贴图长宽相等,符合pot,128-256为主,最大不超过512;
  • 去除 IK 节点和所有不必要的网格,对齐模型中心点与坐标原点;
  • 预先规定好角色需要换装的所有节点名称,并且将需要换装的部分规定好并制作时拆开;(建议将脸部单独拆卡,脸部可增加面数);
  • 角色骨骼30-35根为主,特殊大boss适当增加,超过40慎重考虑;
  • 可以考虑动画帧率10帧每秒,视具体情况或者不限制;
  • 粒子单个发射器不超过50,每个特效最好10个粒子以下,同屏不超过500(200太低难以达到),尽量减少材质和粒子种类,大小,面积,层叠数等,粒子真的很费;
  • 摄像机一定要调整远近裁剪面,尽量降低远近裁剪面的距离,默认数值过大,也千万不要图方便设置比如 0.1-2000这种,该数值极大影响低端机的深度缓存精度,引起过近的物体穿插闪烁;
  • 使用最简单的线性雾,同时善用雾效和摄像机的 culldistant 功能,裁剪掉雾效淹没出的场景部件;
  • 可向程序提出贴图导入自动处理工具,比如角色贴图:普通贴图 _D 结尾,法线贴图 _N 结尾,导入时工具自动设置大小和格式;
  • 如果某个资源大于5MB,那么要仔细查看是否真的必要;
  • 如果成使用工具完成的资源检查和设置,那么都尽量提出需求让程序满足;
  • 最好有个人专门负责检查和整理资源;

以上只是摘取了一部分影响比较大的提了出来,也有一定的项目类型针对性,请根据自己的项目酌情参考和调整,实际细节还是比较多。另外,美术同学要善用 Unity 已经提供的各种工具,比如:面数, DrawCall,OverDraw 等等,这些都是直接又重要的基础指标,需要随时关注。美术同学也可以一开始不需要非常清楚这些标准背后的含义,尽量地去贯彻执行,久了就慢慢能理解,有空自己多去思考和追究;这些标准可以为少数情况酌情开特例,但不要太多。
题外话,13年左右,当时有一款手游叫《天神传》,这个项目的美术印象特别深刻,当年的 itouch4 也能流畅无阻的运行,场景美轮美奂,各种安排十分合理,可见这个团队的美术同学(尤其是关卡)对于 unity 引擎的理解和把控十分了得。

以上纯属个人意见,不一定都正确,欢迎讨论。
感谢UWA 问答社区的 Yaukey提供了以上回答。

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


性能

Q3:我们用Unity做2D游戏,DrawCall多少才能一直顺畅?

流畅这个问题并不一定是Draw Call的锅,具体还是需要查看研发项目的运行性能瓶颈到底在哪里,建议通过查看UWA 性能报告中的CPU耗时占用页面,来定位具体是哪些函数造成了性能瓶颈。

请输入图片描述

虽然我们在报告中目前建议总体Draw Call的整体范围控制在[0,200]区间内,但其并不是一个保险的数值,特别是2D游戏,其渲染的耗时很大一部分可能是Sprite和UI的渲染开销,就这种情况,还没有一个放之四海而皆准的建议。因此,只能建议题主来具体查看渲染模块中的具体开销(类似于下图),并就具体瓶颈进行具体优化。
请输入图片描述

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


内存管理

Q4:这张截图中的10.2KB,我看了UnityEditor的代码,写的是AnimationClipStats.size。但是我看Profiler里,这个动画加载进来以后占内存是29.9KB,那么这个Size是什么呢?真的是内存大小吗?
请输入图片描述

首先需要确认在Profiler中看到的29.9KB是否是在连接真机的状态下看到的。如果没有连接真机而只是在editor中使用Profiler,看到的内存大小并不是动画文件在真机上的内存。在之前的试验中发现,在Inspector中显示的内存大小(这里的10.2KB)与文件在真机中的内存大小更为接近,虽然有时会出现极小的误差。


动画

Q5:请问我一个MeshRender的显示层级能不能夹在一个Canvas下的两个UI节点下?我通过设置MeshRender.sortingOrder数值在两个Image的Render的sortingOrder数值之间 ,是否能做到呢?

Image的sortingorder设置通常是无效的,因为UGUI会对DrawCall进行合并,调整其渲染顺序。因此,需要将Mesh前后的UI元素拆分到不同的Canvas中,从而直接设置Canvas的sortingorder。


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