Unity优化总结
我们的游戏已经在wp8、ios和android平台上线了。这是我做的第一个Unity项目,期间遇到过不少困难和挫折,但是我和小伙伴们一路摸索,现在,游戏已经上线一段时间,并且很稳定。对于Unity,我一直在项目中学习,我会写一系列的文章记录自己的学习,希望看到文章的朋友多多交流。
项目中后期,我做了一些优化工作,这里记录总结一下。
非GPU支持的纹理格式,需要经过CPU解码;而GPU支持的纹理格式,GPU直接解码和显示,GPU的解码有很多优化,随机访问、快速寻址和并行解码等,因此效率高得多。而且,压缩过的纹理文件通常更小,比如ETC1是8:1的压缩比,文件小就意味着加载更快,更节约系统带宽。在手机上对比测试一下加载一个1MB的文件和一个8MB文件的耗时吧。
在ios设备上,建议选择PVR格式。wp8和win8设备上,DXT格式。android设备,不透明贴图选择通用支持的ETC格式;而透明贴图,4大GPU厂商各自有自己的压缩格式,可以选择RGBA16。
实测效果:显著提高渲染表现。我第一次打wp8包在lumia 520上运行,比较卡,声音有卡顿;改纹理压缩格式为DXT1/DXT5之后,在lumia 520上运行比较流畅,声音卡顿现象也没有了。
另外,贴图建议做成方形的,一般不要超过1024x1024。我们最初在lumia 520上偶尔有纹理丢失现象,后来我把几个2048的贴图拆成1024x1024的,问题再也没有出现过,原因没搞明白,知道的朋友朋友请不吝赐教。
2. 限帧
在移动设备上,Unity默认是60帧/秒,建议关掉垂直同步,把FPS限为30,进入后台时为1。限帧可以显著的减少发热和耗电。
3. 图集/材质/Mesh合并
我仅仅通过优化图集,就将游戏的内存占用降低了30M。而且,因为DrawCall减少了,游戏中一个比较复杂的关卡列表界面,渲染耗时减少了一半。
4. 资源优化
我们的战斗场景是3D的,我测试的时候发现这个3D场景渲染表现很差,打开战斗场景,在Galaxy S4上竟然只有35FPS左右!要命的是我们没有美术,美术都是外包的,外包那边的同学不懂移动平台的优化。我找了一些美术优化的文章发给他,估计他也没看懂,他改了几次,渲染表现没有任何改善。最后只能我自己上阵了,我看不懂那些种类繁多的美术资源,采用最笨的二分法,最后查到一个水花溅起的烟雾效果是性能瓶颈。这个效果的表现力很弱,跟产品、策划和美术商量之后把这个效果关闭了。然后,比S4次很多的手机也能跑满60FPS了。
5. 脚本优化
很多时候,性能瓶颈点不在于渲染,而是脚本代码!我们要删除脚本中为空或不需要的默认方法,尽量少在Update中做事情,脚本不用时把它deactive。
经过以上五步优化之后,在lumia 520,iphone 4和三星9100上测试,游戏都可以达到60FPS,满足了上线需求。但是,因为战斗场景元素最多,渲染表现最差,而且玩家在战斗场景中的时间最长,我后面又针对战斗做了一些优化。
6. 资源卸载、垃圾回收
策划的同学反馈过,战斗的时候,偶尔会卡顿。仔细观察之后发现,是有规律的定时卡顿,然后检查代码发现,出于内存优化考虑,terender同学设计了每30秒自动进行一次资源卸载,资源卸载有时候还会触发GC.Collect()。改为进、出战场时卸载资源,而战斗中不再卸载,解决了偶尔卡顿的问题。
7. 资源预加载
以空间换时间的方法。进入战场时,预加载战斗特效和卡牌,减少加载卡牌和发动技能时的帧数下降。这个地方,我最开始写成了阻塞式,后来发现会影响玩家进入战场的体验,改成了非阻塞的,用协程逐个加载。
8. 优化战斗卡牌渲染
经过前面那些优化之后,我仍然不满足,一直在寻求继续的优化,让玩家的战斗体验可以更好。
我们战斗时DrawCall能达到120个左右,我一直在考虑怎么降低DrawCall,3D场景占了20多个,这块没法优化了(没有美术啊%>_<%)。我就把目光盯向卡牌,战场上最多可以有20张卡牌,所以,卡牌是DrawCall的“贡献大户”。先问问策划,卡牌上是否有可以不显示或者合并的内容,策划的同学们寸步不让。吃了闭门羹,只能回来自己琢磨,后来终于想到,显示的内容我无法减少,但是我可以把所有的内容渲染到一起,这样以后绘制时只需要绘制渲染出的纹理而不需要绘制卡牌上“零散”的内容。
卡牌上有卡像、卡框、种族、等级、名字、等级、攻/防等,贡献了5、6个DrawCall,而这些内容除了攻/防数字,别的内容在战斗时都不会改变,把他们渲染到一张纹理上,DrawCall就只有2个了:渲染出的纹理和攻/防数字!ps: 后来我觉得,攻/防数字也可以和别的内容渲染到一起,相对游戏的帧率,数字改变并不算频繁,每次数字改变重新绘制并不会带来显著的开销。
想明白之后,实现就很简单了。然后,我分别打好wp8、ios和android的包,激动的测试,每个平台测试了至少30分钟。测试结果是:DrawCall降低了一半,帧数提高到了原来的2倍。而且,之前一直未较好解决的发热问题,完全解决了。在战场中打了30多分钟,lumia 520、Galaxy S4和iPhone 4s微微温,iPod Touch5,完全是凉的。对比了一下当前正火的《刀塔传奇》,完胜:-D。
以上就是我在做我们的项目时,摸索出的适合我们游戏的一些Unity优化方案。因为我们的游戏是2D的,所以可能对于3D游戏的优化,有些方案可能并不适用,也不够全面。目前有些地方,我们做的也不是很好,优化是一项长期、持续的工作,后面我还会一直进行下去。
下一篇文章预告:Unity自动打包工具,一键打包几十个渠道/平台。