遊戲開發效能優化經驗總結
最近談了許多Unity相關的東西,這篇博文就將一些更加寬泛的東西,算是這段時間裡遊戲開發的一些經驗的總結吧。
優化概論
說起遊戲的優化,在遊戲開發中經常分為這幾步:
- 首先要確定遊戲中經常會出現哪些問題 – Profile
- 然後確定在哪些方向進行效能優化 – Analyze
- 最後再儘可能將問題逐個解決 – Solve
遊戲開發中一定是先做工具,進行Profile,再進行優化,所以,說優化就不得不再扯一下Profile
常見的工具有一些是引擎和IDE自帶的,比如Unity自帶的Profiler,就包含了CPU,GPU,Memory等等各式各樣的效能分析工具,其他的比如GPA,Xcode Instrument和Visual Studio,Intel自帶的記憶體管理工具在必要的時候也使需要去學習和使用的。
另外一些工具,就需要根據遊戲的需求去編寫了,比如一鍵關閉所有特效,一鍵更改解析度等等,一鍵設定場上NPC數量,簡單的遊戲如啪啪三國是做成快捷鍵開啟Profile功能的,更為複雜的遊戲如神祕海域則是通過遊戲內控制檯來進行更為細緻的Profie。
接著,我們再來說說遊戲優化中主要的四個考慮方向:
CPU
引發的問題:
- 由於短時間內的計算量太大,導致畫面流暢性降低,俗稱跳幀
- 發熱嚴重,耗電量高
常見的優化手段:
- 將計算分到多個邏輯幀中進行計算,避免短時間內的效能超過負荷,俗稱“分幀”(time-slice)。
- 將可以快取的資料儘可能的快取起來,避免重複計算和重複分配記憶體,常見的示例為“記憶體池”。
- 使用合理的演算法和資料結構,比如:氣泡排序和直接插入排序在整體陣列比較有序的情況下效率大大好於快速排序。把快排替換成是優化程式排序效率的一個常見的思路。
GPU
引發的問題:
- 發熱嚴重,耗電量高
- FPS降低
常見的優化手段:
- 優化美術資源,比如合理規劃圖集,約定好模型的最大三角形面數,制定合理的粒子效果規範。這個可以說是遊戲優化中最重要的一個,因此,技術美術在遊戲開發中作用巨大。
- 簡化或者優化著色器(shader),如在遊戲開始前就對Shader進行編譯和載入。
- 使用Batching,儘量減少DrawCall
- 使用平臺推薦的壓縮格式,比如安卓平臺的ETC1和IOS平臺的PVRTC
IO和網路
引發的問題:
- 網路延遲甚至掉線
- 載入資源導致的跳幀
- 載入時間過長
常見的優化手段:
- 使用獨立的執行緒進行載入,有些引擎如Unity中還能利用協程
- 減少網路包裡面的冗餘資料
- 合併小包,減少請求資料的次數
- 分幀對回包進行處理
- 限制一定時間內的發包頻率
記憶體
引發的問題:
- 閃退和卡死,比如安卓的Low Memory Killer會在低記憶體情況下殺掉記憶體佔用過大的程式。
常見的優化手段
- 動態載入和解除安裝資源,比如在遊戲內的時候,我們可以把遊戲外的一些UI圖集解除安裝掉。
- 降低資源質量或螢幕解析度,這是有損優化,一般作為最後的手段
對做過專案的一些思考
需要關注非功能性需求
這一點思考是我從為什麼很多看起來不是很複雜的網站,比如 Facebook 需要大量頂尖高手來開發?這個答案中想到的,正如這位答主所說:
事實上,從我的經驗來看,一般來說,很多軟體專案及產品,其在非功能性需求上的成本,難度和工作量,是要超過功能性需求的。在特定的軟體領域,例如網站(尤其是淘寶,facebook這樣海量使用者規模的網站),金融(銀行證券),電信領域,其非功能性需求實現的重要性,工作量,技術難度要遠遠遠遠大於功能性需求的實現。而且,功能性的需求的實現,其實在大多數情況下,更依賴於業務的高手(或者好的產品經理)而不是技術的高手,而非功能性需求的實現,恰恰是挑戰技術高手的重要課題。
在遊戲前端這邊做了一段時間,大家都在抱怨遊戲前端技術含量低,只能寫業務邏輯,但是其中的陷阱就是,作為前端,你應當儘量少寫業務邏輯,你關注過一下的模組嗎?
- 效能:你有沒有在自己的遊戲中進行Profile,觀察在以上各個引數有沒有達到指標
- 安全:你的遊戲前端程式碼的Release版本是否還能被別人輕易反編譯,你的遊戲是否還能輕易被玩家擷取網路包或修改記憶體資料
- 可測試性:你的前端程式碼能不能進行單元測試,能不能在QA測試之前就把Model層的所有bug解決掉
- 資料驅動:你能不能做出更優秀的工具來給美術和策劃使用,解放他們的生產力?
需要善於劃定範圍,縮小問題區間
我在過去幾個月裡,參加了全民突擊和崩壞學園2兩個Unity3D專案的開發,也遇到了一些效能優化相關的問題,在程式出現問題時,很多時候我們會通過所謂的“經驗”去解決問題,這種Quick Link
的能力自然是非常重要,但經驗並非萬能。
但是從另一方面來講,當我們無法從自己過往的經驗中找到答案的時候,我們就要通過劃分範圍,縮小問題區間來解決問題了,許多人往往只是在自己的經驗中死守一個區域性的視野去處理問題,最後的結果就一定不能盡如人意。
總結
其實這四個方面的優化總是相互制衡的,你把一個方面的優化做好了,另一個方面的問題又會出現了,比如,我們如果使用動態載入和解除安裝資源,這就雖然減少了記憶體佔用量,會在IO上造成載入時間延長的問題。
所以,我們在做遊戲優化的時候,不能太追求完美,剛剛好就是真的好(Good Enough Is Fine)。最終使得以上這四個方面能達到均衡即可,切忌在某一方面優化過頭,又引發其他方面的問題,此消彼長的情況下,有時反而不如不做優化。
相關文章
- JVM 優化經驗總結JVM優化
- SQL 優化經驗總結34條SQL優化
- SQL優化經驗總結34條SQL優化
- Java集合類操作優化經驗總結Java優化
- SQL優化經驗總結34條(一)SQL優化
- SQL優化經驗總結34條(二)SQL優化
- 效能優化總結優化
- 總結使用Unity 3D優化遊戲執行效能的經驗Unity3D優化遊戲
- Java 效能優化之——效能優化的過程方法與求職面經總結Java優化求職
- React 效能優化總結React優化
- canvas效能優化總結Canvas優化
- React效能優化總結React優化
- 前端效能優化總結前端優化
- iOS 效能優化總結iOS優化
- iphone 遊戲開發 失敗經驗 總結iPhone遊戲開發
- 元件庫webpack構建速度優化經驗總結元件Web優化
- Android效能優化——效能優化的難題總結Android優化
- 小程式效能優化總結優化
- App瘦身、效能優化總結APP優化
- 系統效能優化總結優化
- 前端效能優化常用總結前端優化
- web前端效能優化總結Web前端優化
- Android效能優化總結Android優化
- 打個總結:Web效能優化Web優化
- ⚠️Flutter 效能優化實踐 總結⚠️Flutter優化
- 總結前端效能優化的方法前端優化
- MySQL的SQL效能優化總結MySql優化
- PHP的效能優化方法總結PHP優化
- UI技術總結--效能優化UI優化
- mysql查詢效能優化總結MySql優化
- 常見效能優化策略總結優化
- LAMP的思考:效能優化總結LAMP優化
- Python效能優化技巧總結Python優化
- oracle 學習總結(效能優化)Oracle優化
- 資料庫效能優化總結資料庫優化
- JavaScript 程式碼效能優化總結JavaScript優化
- oracle 最佳化經驗總結Oracle
- 詳解SQL效能優化十條經驗SQL優化