(转)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。

    \ \ 

    优化前,场上12张卡牌,FPS 112.7 优化后,场上14张卡牌,FPS 208.6
    DrawCall 70,Tris 2.1k,Verts 3.7k DrawCall 47,Tris 1.4k,Verts 2.3k

    从上面的对比图可以看到,渲染优化之后,虽然卡牌更多,但是FPS仍然提升了近一倍,优化的效果非常好。卡牌越多,优化的效果会越显著。

    以上就是我在做我们的项目时,摸索出的适合我们游戏的一些Unity优化方案。因为我们的游戏是2D的,所以可能对于3D游戏的优化,有些方案可能并不适用,也不够全面。目前有些地方,我们做的也不是很好,优化是一项长期、持续的工作,后面我还会一直进行下去。

    下一篇文章预告:Unity自动打包工具,可以一键打包几十个渠道/平台。

阅读更多
文章标签: unity 优化
个人分类: Unity相关
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭