1. 程式人生 > >Unity專案開發過程中常見的問題,你遇到過嗎?

Unity專案開發過程中常見的問題,你遇到過嗎?

最近看到有朋友問一個unity遊戲開發團隊,需要掌握哪些知識之類的問題。事實上Unity引擎是一個很靈活的引擎,根據團隊開發遊戲型別的不同,對人員的要求也有差異,所以不能一概而論。但是,一些在Unity專案開發過程中常常會遇到的問題還是可以總結一下的。

下面我就來聊聊實際工作中,一個專案組可能會遇到的問題吧。

0x01.專案前期規劃時的問題

這裡指的不是策劃的需求或者遊戲玩法的計劃,而是作為一個Unity專案我們需要在一開始明確並制定好的規範和標準。作為一個Unity專案或軟體專案,這部分是很重要的,因為專案早期的規劃隨著專案的開發時間越久,就越難以修改。



對支援的最低機型不明確
作為一個Unity專案,我們首先要明確我們所需要支援的最低裝置標準。並且專案組要有這樣的裝置,以供開發和QA團隊使用。
否則,對專案的優化將無從談起。


資源標準不明確


開發過Unity專案的同學可能都有過類似的經歷,即開發過程中的資源標準不明確。這常常也是早期在專案規劃時沒有重視資源標準導致的。
所以在專案的早期階段,最好能夠明確資源標準比如模型的vertex數量、紋理資源的尺寸格式等等。
也要對每幀開銷中,指令碼和渲染所花費的時間有一個目標和預期。


沒有合理的Asset流水線
這裡指的是資源應該按照一定的流程和標準從美術那裡匯入到Unity專案中。
很多專案最終出現效能問題,都是由於沒有一個合理的Asset流水線。從而導致專案內的資源標準無法管理,很多冗餘或不符合目標裝置水平的資源構建進了最終的安裝包裡。
所以,作為專案組,大家一定要指定一套自動化的Asset流水線。為Asset的規格和標準制定明確的規範,在自動化指令碼中進行設定。
例如texture是否開啟read/write?texture的壓縮格式?尺寸?非人形的model在匯入時是否關閉了rigs?動畫模型是否開啟了Optimize Game Object選項?等等。


沒有合理的構建和QA流程

也有很多專案的構建並非一番風順,構建的版本也難以管理。策劃或者QA常常是找負責某個功能的開發兵荒馬亂的打一個包出來。
所以專案組可以思考一下下面的幾個問題:
是否有專門的打包機?
一個新的功能是如何釋出到最終的釋出版本的?
是否有自動化的可持續整合設施(CI)?
QA要如何反饋Bug,Bug如何有效的管理?


正式專案直接在Demo原型上進行開發
這個也是一個常見的情況,有些專案組早期會有少數幾個人開發一些玩法演示Demo,Demo被認可之後開始開發正式的專案。
此時會有一個問題,即在Demo的基礎上直接開發正式專案。由於很多Demo只是為了演示玩法,所以程式碼中有很多為了儘快實現需求的特定Hack。
如果正式專案以此為基礎,到後期維護會比較麻煩。



除了上面所提到的問題之外,還有一些別的需要重視的內容,例如制定統一的編碼規範、確定採用的光照模式(RealTime?Mixed?Baked?) 等等。

0x02.專案開發過程中的問題

經過了專案早期的規劃階段,來到專案的開發階段時專案組有可能會犯哪些錯誤呢?一些不好的實踐有可能會拖慢專案的開發進度以及讓專案組成員的焦躁感上升。


不重視版本管理
很多團隊對版本管理不重視,或者團隊內部對版本管理例如git的操作不熟練。
當然,關於git的最佳實踐的資料有很多,建議專案組在內部進行培訓和普及,讓大家(程式美術策劃etc)對版本管理的操作符合規範。
針對Unity專案,serialization 的格式建議設定為text serialization。
設定commit hook:

https://github.com/3pjgames/unity-git-hooks


靜態資料儲存在Json或XML檔案儲存
不少團隊喜歡或習慣於使用Json檔案或XML檔案來儲存一些靜態資料,在遊戲執行的時候載入使用。但是使用Json或XML檔案儲存資料會有以下的問題:

  • 載入速度慢。
  • Parse的時候會產生記憶體開銷。

所以資料最好使用二進位制來儲存,在Unity內部也提供了ScriptableObject來幫助儲存資料。


專案中包含了沒有用到的資源、外掛或冗餘的庫
這也是很多團隊中常見的一個問題。一些廢棄的資源沒有及時處理,仍然留在專案中甚至被構建進入了最後的釋出版本,從而造成不必要的開銷。
另一個問題是冗餘或多份同樣功能的庫,比如專案中使用的外掛中有多款外掛都使用到了Json解析庫,那麼就會造成冗餘。

只在Editor中測試效能

這是一個很不好的開發習慣。因為在Editor中測試的是Editor的效能開銷,而不是在真正的目標平臺上的效能開銷。所以在做Profile的時候,一定要在目標平臺的裝置上進行。否則只能得到讓人誤會的資料,例如在Editor中,GetComponent這個API會產生堆記憶體的分配,但是在真機上並不會產生堆記憶體的開銷。

詳情可以檢視:

https://zhuanlan.zhihu.com/p/26763624

當然,更可怕的是真正的效能瓶頸被隱藏了,這樣只會讓Profile變成一件浪費時間而又沒有收益的事情。

開發者不瞭解Profiler工具

在開發Unity專案的過程中,常用的Profiler工具主要包括以下幾種:

Unity提供的:

  • Unity自帶的Profiler:
  • Unity內建的Frame Debugger
  • Memory Profiler:

移動平臺相關的:

  • Xcode Instruments
  • Android Studio
  • Mali Graphics Debugger
  • Snapdragon Profiler
  • Renderdoc

在專案後期才進行效能分析和優化

在開發的過程中就應該關注專案的效能問題,在日常的工作中就應該重視效能分析,而不是等到了專案後期甚至是deadline前才進行。

一方面是能做到對專案的效能問題心中有數,不會在後期手忙腳亂。

另一方面能夠及時發現問題,修正工作流程,不至於“開發債務”越積累越多。

0x03.寫程式碼時的問題 

開發者不瞭解Unity指令碼的生命週期

有一些開發者由於不瞭解Unity指令碼的生命週期,而出現一些程式上的錯誤和問題。

例如引擎什麼時候會呼叫Awake、OnEnable、Update等等API?協程在什麼時候會被更新?FixedUpdate又是怎麼執行的?

可以參考Unity的文件:

https://docs.unity3d.com/Manual/ExecutionOrder.html

FixedUpdate的執行可以檢視:

https://zhuanlan.zhihu.com/p/30335370

過於重度的使用MonoBehavior以及Update

有些開發者喜歡在製作Demo甚至時正式開發專案的時候大量的依賴MonoBehavior以及Update方法。在Unity中MonoBehavior指令碼的Update方法會被引擎記錄在一個List中,在執行時引擎會遍歷這個List,並呼叫其中的Update方法以實現指令碼邏輯的更新。但是,原生程式碼到託管程式碼的呼叫總是會有效能上的開銷的,因此場景中的MonoBehavior以及Update過多會影響遊戲的效能。

相關文件可以參考:

https://blogs.unity3d.com/cn/2015/12/23/1k-update-calls/

沒有對需要頻繁訪問的資料進行快取

這也是一個初學Unity的開發者有可能會犯的錯誤。要對需要頻繁訪問的資料進行快取,以避免不必要的效能開銷。

例如訪問Camera.main,其背後的實現是FindObjectWithTag,因此如果沒有對這個值進行快取,那麼每次都會呼叫

FindObjectWithTag,這是一個開銷很大的操作。

另一個常見的情況就是GetComponent,對它的返回值也要進行快取,以避免不必要的開銷。

頻繁例項化時不使用快取池

​這一點其實並不是什麼新的觀點,或者是什麼高階的知識。但是仍然有很多開發者可能忙於業務功能的實現,而沒有對此給予相應的重視,造成了效能上的瓶頸。

例項化操作是一個比較耗時的操作,所以切記當需要頻繁例項化時,建立一個池,並對其中的物件進行復用。

不瞭解會造成堆記憶體分配的API

C#的GC操作是造成遊戲卡頓的一個常見原因。因此,對指令碼堆記憶體分配的優化是很重要的。這裡可以使用Unity的Profiler來檢測堆記憶體分配,除了重視堆記憶體分配很多的幀之外,對數量不起眼但是每幀都會有堆記憶體分配的方法也要重視。

Unity開發中,常見的會帶來堆記憶體分配的API主要有LINQ、String相關的操作以及返回Array的Unity的API。

例如Physics.RaycastAll,這個API每次呼叫都會返回一個Array的拷貝,因此更好的選擇是使用RaycastNonAlloc來代替。

還例如很多開發者喜歡在檢測使用者輸入時使用Input.touches,對這種property的訪問也會帶來一次Array的拷貝,所以更好的選擇是Input.GetTouch。

0x04.圖形以及UI開發中遇到的問題

專案的Overdraw太多了

這一點主要是開發移動平臺專案的團隊需要注意的問題,Overdraw是導致圖形效能瓶頸的最常見的原因之一。所以要避免渲染不必要的半透明物體,也可以使用更復雜的mesh來勾出半透明的區域。

製作UI時遇到的種種問題

UI系統也是導致很多專案出現效能問題的原因,下面Unity官方公眾號總結出的《Unity UI效能優化技巧》是十分有參考價值的。

0x05.提醒

不基於資料來優化

今年Unite Berlin上,Ian做的一個Presentation的圖片可以很好的說明這一點。

除了資料,不要相信任何人,更不要迷信自己的經驗。通過之前提到過的各種效能測試工具來獲取目標平臺上的真正資料,根據資料分析真正的效能瓶頸。並進行調整、對比來確認問題真正的得到了修改。

-EOF-

最後打個廣告,歡迎支援我的書