如何优化基于Unity开发的3D移动游戏

发表于2015-07-21
评论0 2.2k浏览

想免费获取内部独家PPT资料库?观看行业大牛直播?点击加入腾讯游戏学院游戏程序行业精英群

711501594

基于Unity开发的3D移动游戏优化,它有一些自身的限制,目前我们开发游戏的时候,一方面希望在手机上可以看到3D效果,另一方面又受到3D的限制。我们在开发过程中应当怎么控制自己的行为,在3DUnity上面取得非常好的效果呢?

我列了几个在Unity3D上开发的手机游戏效果,杀出重围、陨落、使命召唤突击队、这是赛车的游戏。移动互联网发展到今天,要想在手机上实现酷炫的效果不是不可能的。Unity3D已经做了很多的工作,但是不是说大家可以任意应用我们的资源,我们想的还是优化。 移动机的弱点就是内存小,首先是散热的问题。其次计算能力相对PC来说比较弱,传输能力也比PC弱很多。我们在移动平台上做出好游戏,就要对资源进行优化,对流程进行控制。

从资源角度来讲,分为动态物体,静态物体,纹理数据等几个方面。从动态物体来讲,包括主角,NPC,怪物。根据我们的实践经验,建议大家把面片数量控制300-2000之间。大家做的时候都认为真正的主角是5000片,在移动平台上要限制数量。在做角色的时候,尽量用一个skinoed的数量。

shade(音)跟我们所谓的材质的关系,如果把若干张图放在不同的贴图文件当中,用一个shade也需要进行一些切换的操作。我们建议大家在不超过1024贴图情况下,即便支持换装,也要求花在同一个贴图上,有利于提升效力。不要连着用4张,因为我有4个换装部件,尽量压在同一张贴图上。与120根,150根的骨骼相比,我们要控制它。因为很多移动设备上做不了加速,都是靠CPU能力更新。

对于动态物体这种需求会有,但是不是特别多。比如说做下雨的效果,会做小的面片,在屏幕有雨滴的效果。超过300个的话,不管你画什么东西,这个游戏效率就降低了。Unity内部提供了标准的处理方法,我们需要对雨滴模型进行重新组织。对于静态物体我们应该控制网格数,一般控制500个以下,要数用static,这些模型具有相同的材质,而且是Unity自动操作的。

大家在Unity里面创造一个新的组件的时候,不管它是静态的,还是动态的,都需要一个组件。任何一个组件都需要做更新,对于纯粹静态的物体,比如在地面上放石头,没有动画的功能,希望大家制作的时候要有习惯,在静态的时候,就把这个东西删掉,不影响任何功能,在效率上会有好处。刚才有很多人问地形的问题,尽量单块地形不要超过257×257的大小。如果超过的话就要做一些处理,对每一块都要做一些技巧。如果对于每一块地形的话,我觉得最应该控制不是网格的数量,而是它贴图的数量。

我们游戏团队开发的时候,程序员和美工之间有冲突。程序员认为贴图的时候不应该超过太多,美工就说这个游戏是精品,你一定要支持我的要求。很多程序员都认为这是无理的效果,其实你通过4层就可以达到很好的效果,不一定非要用8层,16层。更极端的一点,如果美工一定要求地表很丰富,你的系统就是满足不了我的要求,4层一定达不到我的要求,你要求它画28层,38层都可以。我们做一个离线的要求,最后只剩一层,这也是解决方案。美工一定要求这么做的话,你愿意做这件事就去做,但是最终在地表上只有一层贴图。大家做纹理的时候,通常的格式就是png,或者cga,希望大家把它做成长宽相当。通常来讲,在内存里面都会开一些catch(音译)的结构,如果你内存是1024×1024。这块是空着,你下一个内存可以应用这部分空间。贴图不是越大越好。美工会认为,贴图分辨率越高越清楚,我们不能说这是错的。

举一个简单的例子,把世界名画放在300米之外看,怎么也看不清楚。最终依据物体投影出来的像素多少来决定贴图使用什么样的规格。我们建议大家生成mipmap,虽然它有一些损耗,但是也可以提升效率。mipmap也没有把层数启动的特别高,通常2-3层就可以了。我们建议美工画UV的时候,尽量画0-1之间。有的化工画在0-1之外。生成的时候,都要进行UV的转换,我们要求美工尽量画在UV之内。播放时间比较长的音乐,建议大家使用压缩的格式,但是如果对一些瞬时的技能特效的,还是要采取压缩的,大家要做一个平衡。

程序包的大小,尽量把贴图做到合适就好,不要强调分辨率越高越好。对于网格和动画,我们希望大家做到够用就可以了,比如说我们有一些很好的第三方的工具,比如system对网格可以简化。我们做程序的时候可以使用这样的工具。在程序开发到一定节点的时候,对以往的资源做一个优化,如果某些模型超过标准了,就可以用这个工具。大家尽量不要用比较大的工具。

Unity引擎相关的优化

现在我讲一些跟Unity引擎相关的优化,这包括光源,相机,渲染等等。大家知道Unity里面有一个光源选项叫important,如果大家懂了,就会很注意这个事。我们建议大家采用方向光源,不要采用点光源。Unity还有一个选项叫pivel lightimportant光源是潜在的一个光源。美术制作这些光源的时候,可以把它勾上,但是还有一个总控的开关叫pixel light

大家做游戏的时候,可以指定距离。Unity里面有一个lea(音译)的概念,你可以把场景里面大规模的物体放在这里面。中等规模的放再一个lea里面,小的放在一个lea里面。对于大的物体的话,把它指定的远一些。对于很小的,比如说草,或者小石头,我希望眼前有10米,就可以把10米之外的东西都清除,等待渲染的物体的数量就会少很多,这个对提升效率是很有好处的。大家做游戏的时候,就把自己的物体简单分层,为每个层指定可用的距离,可以提升做游戏的效率。

关于粒子,为了让我们游戏做到特效,我们都在拼技能是不是华丽,大家都在用粒子系统,半透明的混合系统。这样的特效在PC上没有什么问题,但是在移动设备上是有一定的问题的。如果大量使用直接的混合的话,就是所谓的粒子,由于绝大多数的粒子都需要启用半透明混合系统。在这样的情况下,要制定一个美术规范,我们建议粒子数量不要超过200个,发射粒子数量不要超过50个。要把粒子数量减少,把粒子大小减少,它混合的是三分之一的屏幕大小,它混合的是四分之一的屏幕大小。尽量不要开启粒子之间的碰撞功能。很多时候大家可能不是故意的,但是有的时候会弄错,粒子碰撞开启的话也是很耗时的工作。

对于物理的话,我们有一些所谓的碰撞体,一定要做简划。这样的碰撞要进行三角形碰撞的比较。尽量让大家用基本的形体,逼近这样的东西。比如说你要的角色是格斗类,要求所有的都要有碰撞的效果,用胶囊逼近它,不要直接匹配它,这两个不是一个数量级的。对于地表的环境和石头更容易了,直接采用基本的形体逼近一下就可以了。

大家不要在移动平台上考虑用alpha或者mlpha。比如说对于静态的物体,最好旁边打一个勾,Unity就可以帮大家处理后续的事情了。前提条件要求大家做这样的工作。很多时候我们的美工也好,程序也好,虽然都知道这样一件事情,都知道它可以提高渲染效果,如果你花一点时间,对自己的游戏项目做一个彻底的梳理。如果没有特殊处理的话,100%的游戏都有错标。该标的静态物体没有标上,会发生遗漏的现象。这个问题的解决方法很简单,大家可以开发插件,做最简单的Unity的小插件,把自己所有场景里面的物体列出来。这时候隔一段时间检查一下,我确信通过工具的检查方式,一定会取得一个很好的效果的。隔一段时间打在纸上看一下,我这个物体明明是静态的,怎么变成动态的呢。大家不要明明知道这是很容易发生的小的疏忽而不去理睬它。

 

对于动态来讲,我们不要滥用,它的概念很好,在很多时候,动态物体可以做bashino(音译)。最极端的情况下,我们支持小于900个顶点的物体的合并。如果再有其他的属性的话,可能就是300个,数字要求是非常严的。更多的时候,就是前面我说的第一个例子,它是最适合的,但是不要滥用,大家一定要知道,是有一定限制的。

对于纹理来讲,我们要进行拼合,在很多情况下进行纹理拼合大幅度的提高渲染效率。Unity引入的很好的第三方插件,这是芬兰的一个小公司提供的插件,是非常好的东西。它对每款式游戏收费费用是2500万美元,继承之后就开放给大家使用了。如果你做PS游戏情况的时候,在场景里面会有大量的遮挡的情况,一定要启动这个,它会事先对场景做一个烘焙。这样的东西在场景特别丰富的情况下,对于提高渲染效率是有很大提升的。这里面我们分为遮挡者和被遮挡者。对一些细节我们还有选项。这三个选项最后的细节力度最高,耗费的时间也最长。我相信GUI用户不多,但是用的话,大家要注意,这里面的贴图不要太大,大尺寸不会在内存里面,长宽是4的倍数才能被压缩。

Unity3.X4.X对静态纹理有比较大的提升。这是没有经过优化的,大家指定了32D的图,生成3000个汉字,这个需要2048×2048的贴图。如果大家用这个bafont制作的时候,用1024×1024的纹理记录文字就可以了,大小变成了4M,这两个是比较图效果。用这样的方式有好处,也有坏处,这个地方需要注意一下。在现有的移动设备上,我们还是推荐大家使用最新版本。

 

写代码应该注意什么

程序员写代码的时候,需要注意一些最基本的东西。第一希望大家采用静态的类型,比如说这两个代码。通过一个函数你可能比较不出来效率的区别,但是我们希望大家养成一个习惯,作为一个规范,整个项目都遵循这个规范的话就会有一定的区别。我们启用动态加速度的粒形(音译)。我们使用一些组件的时候,要把它设置成自己的权变量。在update的时候每次都要对它进行更新。

这里面有几个不同的update,这里重点讲的是fastupdate,它主要更新物理组件,就是做一些碰撞。如果你的角色在场景中走路,希望他一边走的时候,需要做一些跟地面和墙体的碰撞检测,渲染和动画每桢都要更新。物理碰撞不需要实时更新,对非动作类的游戏,甚至一秒更新10次,或者5次就够用了。这个时候就可以把fatsdatetime多长时间更新一次的频率,这样有助于提升效率。我们勾上这两个选项进行合理的选择,以求自己的程序在不同的程序下,特别是需求来决定到底是哪个要素对你来讲更重要。我们在很多程序里面喜欢写string连接,尽量写成for循环。C++的程序员喜欢用class,但是我们希望大家使用structstruct的内存是在战上的,class是堆上的,struct的效率是比较快的。如果大家做一些例子就会有很深的体会了。上面是用struct使用情况,下面是class使用的情况。建议大家使用资源缓存池方式.

下面我讲一下关于着色器相关的优化。大家尽量避免一些非常非常复杂的数学运算,比如说像指数等等,这些都是很费时的。我们最常见的操作需要计算一些屏幕上的距离,这样的距离建议大家一定不要采用两个平方相加,开方的。建议大家把开方这块去掉。比如说discard的操作,尽量少使用。浮点数计算的时候,不要一味的图简单,不要都使用float,我们要根据计算精度来取决,用什么样的计算精度。希望大家能够注意这些东西。

 

总结

前面讲了很多东西,比较杂。最后做一个总结,要想做出好的优化,第一希望大家尽量的多用Unity提供的内嵌的是profiler,我们针对所有的东西提供比较好的选项。关键的数字都是内嵌在引擎内部的,所以在收集上比外部的工具有优势,尤其是4.2.1版本之后,我们对所有的内存进行分析统计。平时大家做项目的时候尽量使用它,每隔一段时间,对自己的程序和代码进行分析,找到问题,及时修正自己的错误。

要想做出好项目来,优化永远都是补救的措施,更好的措施是在程序或者项目立项之初就有一份非常完备的规范。通常来讲,我们希望每一个游戏团队都可以总结出来像这样的列表。比如说我的物理模块要求我的项目命名规范是什么样的?基本的形体怎样协调规范。对于地形,纹理的尺寸,希望大家能有这样一张表,对自己的项目能有一个合理的规范。

我们一再强调的,即便有了这样的表,也不是完全的措施。因为项目做到一定阶段的时候,我们经常听到程序和美术打架,双方争吵。程序上,项目立项之初给你定了非常详细的美术规范,结果做到现在,你们做的东西,完全没有按照我的规范来。美术也是一肚子苦水,我们领导到每个节点都要检查我们的东西,他说你们的东西满足不了我们游戏的品质,我们是按领导要求做的。我们公司说我们节点做的很好,程序做不好,为什么在我们这儿工作,你可以走。这种冲突是经常有的。我们说互相的埋怨是完全没有意义的,也是不应该发生的。真正合理的方式双方在早期的时候就已经配合了。

我们的程序员和技术美术定立了严格规范之后,直接写一些Unity的工具,然后再做开发是比较简单的。如果你是一个足够牛的人,你可以重新做Unity的编辑系出来,和我们做的是一模一样的。既然我们开放了这么多的接口,大家可以用这样的功能开发很多二次开发迭代的功能。我们把前面定的领域规范固化下来,开发基于Unity这样的工具,每隔一段时间就检查一下。如果大家可以写一些非常简单的工具,过一段时间就总结一下。

有一次我们就出了问题,我们有工具就开始跑一遍,很快就查到美工那里出了一些问题。有时候可能有误操作,或者自己也没有检查模型有多大。人工检查这样的东西,是很难的。如果开发一些小工具,对面片数做一个简单的检查,很多问题都可以很容易的被解决掉了。做好一个项目,需要不断的试验,不断的总结,今天我演讲的内容就到这里,谢谢!

原文链接

著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

游戏学院公众号二维码
腾讯游戏学院
微信公众号

提供更专业的游戏知识学习平台