Unity性能優(yōu)化系列:如何做好Unity項(xiàng)目性能優(yōu)化
前言
在面試中,我們經(jīng)常會被問各種”莫名奇妙”的問題, 比如這道:”你是如何做好Unity項(xiàng)目性能優(yōu)化的?”?!斑@個問題也太泛了吧,沒有具體的優(yōu)化點(diǎn),這怎么回答?” 瞬間躍入腦海。做面試復(fù)盤的時候,你可能會想這個面試官是不是什么都不懂,是個”青銅”啊。沒錯,能問這道問題的面試官要么是個”青銅”, 要么就是”王者”。說他是青銅,可能真的什么都不懂,只是他聽人說Unity 項(xiàng)目做性能優(yōu)化的時候比較麻煩,所以就來問你,看你如何處理。還有一類是王者,就是來考你各方面的綜合能力,接下來我們從
(1)從項(xiàng)目技術(shù)管理的角度來杜絕性能問題;
(2)性能問題定位與分析;
(3)性能問題的常用解決方案;
這3個方向來回答這道很泛的面試題,讓面試官對你”刮目相看”。

?
1:?從項(xiàng)目技術(shù)管理的角度來杜絕性能問題
“性能優(yōu)化”最重要的方式(沒有之一),不是任何的編程技術(shù)與技巧,而是從”項(xiàng)目管理”上防止”游戲做完馬上要上線”時出現(xiàn)的性能問題。在日常項(xiàng)目管理中,把性能監(jiān)控起來,問題盡早發(fā)現(xiàn),盡早動態(tài)清零,這樣才能做到項(xiàng)目從性能風(fēng)險(xiǎn)上是可控的。我的一些經(jīng)驗(yàn)如下:
a:用心做好技術(shù)調(diào)研
我們很多小伙伴不重視技術(shù)調(diào)研,或者技術(shù)調(diào)研做的非常的馬虎,導(dǎo)致對游戲的性能預(yù)估不足。比如我們做渲染管線定制,編寫了Shader,效果出來自己比較滿意,渲染這塊的技術(shù)調(diào)研就結(jié)束了。其實(shí)不然,這個事情才做了1/3不到,還要注意必須要最快的速度盡早多平臺測試(有些同學(xué)的項(xiàng)目真的好笑,到了上線前一晚才發(fā)布到不同的手機(jī)真機(jī)上跑)。你在項(xiàng)目開始就上多平臺,才能發(fā)現(xiàn)各個平臺不同的差異,盡快解決這些差異與問題。同時還要構(gòu)建游戲核心玩法中的極限情況模擬,來應(yīng)對項(xiàng)目后期大量戰(zhàn)斗單元出現(xiàn)導(dǎo)致的性能問題。
b:?從項(xiàng)目正式開發(fā)的第一天起就引入多平臺測試與完整的測試機(jī)制;
這個強(qiáng)調(diào)多少次都不為過,什么時候,哪個改動,引發(fā)了哪個問題,什么時候出現(xiàn)了一個什么樣的問題,如何解決的,作為項(xiàng)目管理者,要一路對這個過程非常的熟悉,只有這樣你才能真正了解你這個項(xiàng)目的穩(wěn)定性。
c:?留出專門時間與專人review代碼;
開發(fā)項(xiàng)目的時,我們需要有專門的技術(shù)負(fù)責(zé)人review整個項(xiàng)目的代碼,了解團(tuán)隊(duì)成員的實(shí)現(xiàn)思路與代碼設(shè)計(jì),把控項(xiàng)目質(zhì)量,確保沒有太大的問題,技術(shù)負(fù)責(zé)人都知道具體是如何實(shí)現(xiàn)的。這樣有非常復(fù)雜bug的時候,團(tuán)隊(duì)至少有人能從整個全局來了解整個項(xiàng)目和代碼。出現(xiàn)性能問題的時候,能從大局著手,進(jìn)行分析組織大家攻關(guān)。
d:?了解運(yùn)行中技術(shù)參數(shù)的變化,做好技術(shù)參數(shù)統(tǒng)計(jì);
開發(fā)項(xiàng)目時,每次有功能完成提交測試后,我這邊會讓測試出一些性能參數(shù)的統(tǒng)計(jì),比如main thread多少,render thread多少, batches多少等。每次數(shù)據(jù)的變化,結(jié)合review代碼,看下是否合理,能夠做到什么時候引入了哪個功能,讓drawcall增加了幾十,是什么引起的項(xiàng)目中作為管理者都要清楚和關(guān)注。
總之完整的工程管理機(jī)制,與測試共存,?動態(tài)清零包含性能在內(nèi)的問題,是做好性能優(yōu)化的最重要的手段。做項(xiàng)目是一個工程問題,質(zhì)量靠管理,不靠程序員的”天分”。(注:防疫動態(tài)清零也是個工程問題)
2:?性能問題定位與分析
當(dāng)項(xiàng)目開發(fā)過程中發(fā)現(xiàn)性能問題后,如何定位性能問題,定位到具體是哪里引發(fā)的,這個就變得非常重要了目前主要的手段如下(按照我認(rèn)為的重要程度):
a:代碼算法與系統(tǒng)底層功底: 為什么大廠老要求算法,OS底層,數(shù)據(jù)結(jié)構(gòu),引擎底層,只有對這些基本的原理原則了解了,思考問題的時候才知道如何分析與解決。比如算法的時間復(fù)雜度,空間復(fù)雜度,比如Drawcall合批所帶來的性能提升與性能開銷的權(quán)衡等。
b:工程管理手段: 通過工程手段測試出來了性能問題,我們可以比對上一次測試與本次測試的開發(fā)記錄,看看是引入與編寫了哪些代碼導(dǎo)致的性能問題,頻閉掉可疑的代碼,反復(fù)確定,這樣能幫助我們瞬間就定位到出現(xiàn)的性能問題。(注:95%以上的問題我都是通過這種對比發(fā)現(xiàn)的,通過開發(fā)記錄對比可疑代碼,屏蔽可以代碼確認(rèn),從而分析問題最后解決)
c: 打印: 沒有打印解決不了的問題,如果有繼續(xù)打印,linux 內(nèi)核的開發(fā)與調(diào)試基本就靠打印,因?yàn)閺?fù)雜的多線程調(diào)度環(huán)境,任何工具都不好定位,所以沒有打印解決不了的問題。
d: 性能工具剖析手段: 通過Unity提供的性能剖析工具,來進(jìn)行問題定位與分析。Unity引擎運(yùn)行中會提供很多API與性能參數(shù)給用戶獲取,而Unity引擎自帶的工具也是調(diào)用這些API獲取游戲的性能,比如stats統(tǒng)計(jì)與Profiler統(tǒng)計(jì)。同時還有一些第三方的插件,也是做性能監(jiān)視的,本質(zhì)也是讀取Unity引擎提供的性能參數(shù)API,把自帶工具沒有顯示出來的重要性能參數(shù)顯示出來給用戶。注:不要迷戀工具,要從管理+數(shù)據(jù)+執(zhí)行流程上對程序進(jìn)行分析,性能工具是做這些分析的方法之一,甚至不是最重要的

3:性能問題常用的解決方案
說到這里了,才是我們很多面試的同學(xué)一開始就回答的,可以用xxxx手段來解決xxx問題??赡芪覀冋f的都對,但是在”王者”面試官看來,他出這個面試題,目的就是看你是否從系統(tǒng)上去思考如何把控游戲項(xiàng)目的性能。定位到了是某方面的問題,再去應(yīng)對一些常用的手段,這里我就把一些常用的列舉一下,可能有遺漏。
Drawcall優(yōu)化: 確定是Drawcall問題后,根據(jù)游戲項(xiàng)目選擇一種合適的合批技術(shù),為這個技術(shù)創(chuàng)建可合批的條件,做好合批,具體可以參考我寫的《Drawcall優(yōu)化系列》教程詳細(xì)的分析了Drawcall合批的技術(shù)手段與原理,性能與開銷(what?合批還有開銷?沒有錯)。
渲染優(yōu)化: 看下pass的次數(shù)與set pass 次數(shù), pass 次數(shù),比如陰影這些都會導(dǎo)致多次pass,多光源這些會導(dǎo)致多次pass, 我們可以通過定制渲染管線,優(yōu)化shader代碼, 優(yōu)化光照計(jì)算等,從Shader+渲染管線級別來做好渲染優(yōu)化,現(xiàn)在比較火的UPR渲染,也可以參考我寫的《URP 實(shí)戰(zhàn)系列》的教程。還有LOD優(yōu)化,遠(yuǎn)處用的面數(shù)少,近處用的面數(shù)多??逛忼X算法優(yōu)化等。
物理引擎優(yōu)化: 這塊化沒有太多的空間了,用其它的技術(shù)去替代不用物理引擎,減少物理引擎的迭代參數(shù),減少計(jì)算量,減少物理剛體的數(shù)目。
網(wǎng)絡(luò)優(yōu)化: 異步IO代替同步IO,多線程處理網(wǎng)絡(luò)消息, protobuf序列化與反序列化優(yōu)化網(wǎng)絡(luò)包體體積。KCP 替換傳統(tǒng)的TCP。
包體優(yōu)化: 優(yōu)化圖片,聲音體積,通過改變壓縮參數(shù)來降低這些資源的體積大小??梢允褂梅?wù)器上部署資源包來實(shí)現(xiàn)打空包機(jī)制進(jìn)一步減少包體體積。
熱更新優(yōu)化:版本管理,增量下載,斷點(diǎn)續(xù)傳等。
內(nèi)存優(yōu)化: 減少資源的內(nèi)存占用,不用的資源卸載掉,吃入顯存的紋理可以采用平臺支持的壓縮格式。緩存池,減少內(nèi)存碎片,減少對象的反復(fù)構(gòu)建,避免GC峰值沖擊等。具體可以看下《性能優(yōu)化-內(nèi)存篇》。
模型優(yōu)化:通過細(xì)節(jié)增強(qiáng),法線貼圖,高度貼圖,凹凸紋理等減少模型面試的同時獲得很好的效果。
尋路導(dǎo)航優(yōu)化: 優(yōu)化算法,流場尋路等,多線程優(yōu)化尋路算法。
代碼寫法優(yōu)化: for循環(huán)內(nèi)部不要過多跳轉(zhuǎn)打亂CPU Cache等?!?/p>
其它的一些具體的優(yōu)化手段,針對不同的問題來做一一的處理就可以了。具體問題具體分析。

如果你是面試官,看到一個年輕的小伙,能系統(tǒng)的思考”性能優(yōu)化”這個工程問題,你會錄取么?
Unity / 性能調(diào)優(yōu)篇
游戲程序員優(yōu)化指南
https://www.bycwedu.com/promotion_channels/695765628