程序丨Unity初学者的性能优化方案
本文参与“Unity性能优化”有奖征文活动,活动详情请点击:Unity文章有奖征集第一期:性能优化。
工欲其善事,必先利其器。
在使用好Unity之前,必须得对它有足够的了解。
关于Unity的简介在这里就不再阐述了,以免有填充字数的嫌疑,既然主题是关于Unity 的性能优化,就得先从Unity的应用方向了解。
一提到游戏引擎,首先就会让人联想到大名鼎鼎的虚幻系列引擎(Unreal Engine):业外人事谈到Unity,总会习惯性的与虚幻引擎相比,觉得与之相比,Unity总给人一种淳朴的乡土气息,“不够专业”、“狗肉上不了酒席”这种带有嘲讽意味的标签纷纷贴了上来,可这些人却不知道,虚幻引擎已经诞生出多少大作的同时,Unity才刚刚出生。
与繁杂的虚幻引擎相比,Unity要更容易使用一些。在如今人人一部手机的时代,Unity在移动端的领域要更为出色。
因为Unity入手简单的原因,很多细枝末节并没有被开发者注意到,等到游戏开发完成再进行游戏优化,宛如给游戏大换血,还不如重做游戏来的快。
Unity的优化方案在网上又大把大把的教学,但我想根据在我身上发生的真实案例来阐述一下。
今年七月份的时候,曾独立开发过一款基于Unity的PC端游戏,期间就涉及到了很多有关游戏优化的问题。
上篇回顾:开发日记:Unity完全自制游戏《纸箱战争》项目记录
之前玩过《使命召唤》、《战地》、《守望先锋》等这些FPS游戏,兴趣使然,也想搞一款自己的游戏出来。
考虑到之后会发布在移动平台上,因此对游戏的性能还要有一定的要求。
因为在同一游戏场景内的敌人数量和友军数量需要达到一定的规模,才能模拟出战场的效果,再加上自负心理妄图实现纯原创游戏,所以一个程序员便玩起了建模,打造出了一个盒子精的人物形象。
如图可见,这是玩家在游戏中的样子,以不同的颜色来区分玩家的阵营。
是不是有点像是《我的世界》中马赛克小人的造型?当然了,这个也是可以后期贴上贴图作为换肤系统来使用的,整体模型框架就是这样。
除了人物之外,游戏场景中的载具和环境也都是由简单的片面图形构建出来,一辆坦克不足500面,就算性能再差劲的手机也可以运行的起来。
同样的,每个游戏都是要有卖点的,可能你的美术特别出色,亦或是游戏性特别新鲜,再或者是数值策划特别平衡,总而言之,没有卖点的游戏就注定会是个残缺品。
在我设想的这款游戏中,我便想到了一个“地形破坏”的设想。
在战争中难免会产生爆炸、枪击。回顾已有的战争游戏,纵然是动视的《使命召唤》系列、EA的《荣誉勋章》系列,还是同样师出同门来自EA的《战地》系列,他们都不能产生地形破坏效果。
甚至是建筑物被破坏的时候也是按照既定的动画替换成破坏过的样子的模型。
在游戏中,玩家对抗坦克的方式只能使用反坦克炮或者是炸药摧毁坦克,如果能产生地形破坏的效果,玩家可能会设想,炸毁地面,制造出坦克不能逾越的鸿沟,又或者炸毁桥梁让坦克跌入水中?又可能是倾倒房屋围困住坦克?
这些都是有可能发生的。
模型网格的切割使用到了SBP技术,基于二叉树算法的一种网格遍历切割算法,不是几天功夫就能掌握的,为了追求速度了原创,便采用了投机取巧的办法,这在小的手游公司中很常见,俗称为“演”。
按照我设想的原理,整块地形受到攻击崩塌成大块泥土,大块泥土受到攻击崩成小块泥土,小块泥土再受到攻击则会蹦碎成土砾。
按照这个想法,简单的模型替换就实现了,而且效果还不错。
像模像样的爆炸,土块飞溅,效果还算可以,但占用性能居多,CPU占用率飙升,多个点位同时爆炸,就连I5的CPU都有些顶不住,更不要提移动平台的那点算力。
框选后发现,无用的废物方块数量过多。
为了达到这种效果,也只有这种办法较为简便,只能从崩坏效果上入手,减小爆炸半径,优化爆炸土块扬起效果。
最后得到了这样的结果:
六个坑洞产生的立方体数量还没有之前一个产生的多,虽然这也是一种笨方法,但对性能的影响已经降低了不少。
六个坑洞产生的最大Batches值仅为34,如果在游戏中需要连续如甬道类坑洞,方块数量会更少。
解决了这一难点后,原以为在性能问题上就不用在耗费心思了,可在进行NPC的AI设定时才发现自己的想法有点天真。
Unity中的Update函数每帧执行一次,游戏运行的越流畅,代码运行的次数也就越多。
为了能让AI执行更有效率,我把AI的逻辑算法写在了Update中,运行起来帧率骤降,最高才能刚刚达到30帧,这还是在PC上运行的结果,估计放在移动端根本运行不起来。
思索后发觉有的代码并不需要多次执行,就比如AI攻击目标的寻获,在短时间内,没有外力作用,不管是人类还是AI都应该是持续不断的攻击一个目标,直到该目标死亡。
AI的根本性质其实也就是模仿人类,AI是人类写出来的,为了完成既定工作被发明出来的,考虑到这点,我把AI大量删改,封装成方法,每隔固定的频率调用或是特殊事件调用。
除此之外都会依照默认事件执行,大大节省了效率。
最后在关于Unity自带的寻路系统中也有一些使用的技巧,可以使得游戏运行效率更快。
比如是给寻路物体附加新的目标点,再不需要改变的时候不要多次赋予相同的值,对于底层代码的调用也是一种负担。
以上就是参照个人项目对Unity性能优化的见解,仅供参考,如有疏漏之处,还望斧正。
↓↓↓点击阅读原文,了解更多。