Unity初學者的性能優化方案
本文參與「Unity性能優化」有獎徵文活動。
工欲其善事,必先利其器。
在使用好Unity之前,必須得對它有足夠的了解。
關於Unity的簡介在這裡就不再闡述了,以免有填充字數的嫌疑,既然主題是關於Unity 的性能優化,就得先從Unity的應用方向了解。
一提到遊戲引擎,首先就會讓人聯想到大名鼎鼎的虛幻系列引擎(Unreal Engine):業外人事談到Unity,總會習慣性的與虛幻引擎相比,覺得與之相比,Unity總給人一種淳樸的鄉土氣息,「不夠專業」、「狗肉上不了酒席」這種帶有嘲諷意味的標籤紛紛貼了上來,可這些人卻不知道,虛幻引擎已經誕生出多少大作的同時,Unity才剛剛出生。
與繁雜的虛幻引擎相比,Unity要更容易使用一些。在如今人人一部手機的時代,Unity在移動端的領域要更為出色。
因為Unity入手簡單的原因,很多細枝末節並沒有被開發者注意到,等到遊戲開發完成再進行遊戲優化,宛如給遊戲大換血,還不如重做遊戲來的快。
Unity的優化方案在網上又大把大把的教學,但我想根據在我身上發生的真實案例來闡述一下。
今年七月份的時候,曾獨立開發過一款基於Unity的PC端遊戲,期間就涉及到了很多有關遊戲優化的問題。
之前玩過《使命召喚》、《戰地》、《守望先鋒》等這些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性能優化的見解,僅供參考,如有疏漏之處,還望斧正。

