您好,登錄后才能下訂單哦!
本篇內容介紹了“游戲引擎Unity的入門知識點有哪些”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
個人認為Unity相比于其他引擎易用性較好的原因主要有:
基于組件(Component)的關卡設計更符合直覺
Unity通過將系統或用戶的腳本抽象為可重用的組件(Component)并附著在游戲對象上來控制游戲的行為。相較于傳統的基于腳本的開發方式,關卡設計師可以更靈活、更快速地搭建界面和關卡,有一種“搭積木”的感覺。雖然這種設計犧牲了一部分擴展性(例如難以實現嵌套Prefab),但對初學者來講是非常友好的。
虛幻引擎4.7版本的更新也效仿Unity,向組件化的方向靠攏,使關卡結構更容易理解和維護。
使用Mono作為腳本運行的平臺
C#/Mono相比C++和其他腳本語言,有更好的穩定性和抽象能力,有容易使用的.NET框架和易于移植的各類開源庫,相對完善的語言服務(如GC和反射)也使開發復雜邏輯容易許多。雖然降低了門檻的同時也讓低質量的代碼更容易產生,但不管對于初學者還是老鳥來說,我覺得都是利大于弊的。
引擎本身的功能相對簡單 + 豐富的Asset Store插件
和虛幻等超級引擎相比,Unity提供的功能算是非常基礎的,組件數量和各組件可配置的內容都不多,所以在學習的時候更容易產生比較直觀的感受,不至于迷失在細節當中。另一方面,Asset Store模式的成功造就了大量功能強大的第三方插件,填補了Unity開發中的各種空白,進一步降低了開發門檻。
而難于精通方面,我覺得主要原因在于:
對綜合能力要求高
首先,不僅對Unity,對任何游戲引擎或者對游戲開發本身來說,想要精通都是很難的一件事。因為游戲客戶端開發本身是一項綜合性非常強的活動,整合的技術非常多,例如:
建模
關卡制作
腳本邏輯
網絡通信
平臺特性集成
動畫制作
特效制作
工作流集成
調試和優化
而對于將這些技術粘合在一起的Unity工程師來說,雖然不需要精通方方面面,但將團隊成員的工作高效率高質量地結合在一起,也是非常考驗其能力的,只有長期地,全方面地參與整個開發過程并了解團隊成員的工作方式,才能逐漸成長為一名優秀的Unity工程師。
舉例來說,Unity工程師需要:
與設計和美術團隊溝通,評估設計對于游戲性能的影響,實現原型,進行各種性能測試。
與服務器工程師溝通,確定互相之間的接口和協議內容的細節。
Unity本身沒有一個Gameplay Framework,場景管理、游戲數據管理等相對底層的框架都需要Unity工程師來搭建,如何減少團隊中其他成員的錯誤實踐,是主程序的責任,也很考驗其架構能力和對Unity Runtime的理解。
一些特效需要自己編寫Shader才能實現。
動畫師和美術團隊產生的資產,根據項目的需要常常要自己寫Pipeline來導入和進行優化處理。一部分還需要以合適的方式打包,供客戶端增量下載,需要對Unity的資源管線有較好的理解才可以。而且看似簡單的決定之中,常常蘊含了很多性能上的考量。
根據關卡設計師的需要,制作編輯器擴展工具,提高其工作效率。這方面的文檔稀少,同時也需要對Unity獨特的序列化機制有比較深的理解才行。
想利用iOS和Android以及各種平臺特有的功能時,需要針對特定的平臺編寫一些Native插件,如本地Push通知,自定義系統鍵盤,系統彈窗等等。要懂一些iOS開發和Android開發的知識才能駕馭。
有些做Unity的工程師可能只是搭建關卡,寫一些控制腳本,而優秀的Unity工程師的價值往往在于其能夠承擔更多的團隊職責。所以說想要精通這些,真的需要付出很多的時間和努力才行。
難在細節
任何事想精通,細節都是非常重要的,比如:
內存管理
避免和排查腳本中的內存泄漏。例如沒有清空的委托和靜態閉包造成的引用。
優化GC,了解Mono和.NET GC算法的差別。比如Unity采用的是較老版本的Boehm GC,不分世代,GC分頁為1KB,內存碎片無法合并,單線程,缺少LOH,托管堆一旦擴大就很難向系統返還內存。如果按照.NET的思路優化GC,有時候并沒有理想的效果。而Unity最近引入的IL2CPP運行時,采用了新版本的Boehm GC,算法又有所改變,優化策略也應適當調整。
了解Unity的內存模型,哪些資源分配在Native堆上,哪些分配在Mono的托管堆上。Native上不同種類的資源分別用哪些方法能夠釋放干凈。Native堆上的引用計數是如何工作的。如何減輕Unity自動釋放場景時的壓力。AssetBundle的內存結構是怎么樣的,各個部分如何不依賴GC而精準地釋放。
暫時隱藏起來的圖片或物體如何暫時性地釋放,在顯示時又如何重新加載回內存。
了解哪些API和操作會分配內存,什么時候使用值類型更好或更不好。這都需要對C#有很深入的理解。
網絡和下載
AssetBundle如何打包,什么樣的圖片用什么粒度打包效率最高。
如果使用Json反序列化數據,怎么才能避免內存碎片降低整個App的性能。
不斷更新的素材需要增量下載,Unity內置的下載方式瓶頸在哪,怎么自己實現一個比Unity內置API更高效的下載機制和更精準的緩存控制機制。
腳本執行
能夠將較復雜的操作(如反序列化數據,較重的IO操作)放在后臺線程執行,再調度回主線程更新游戲界面,以避免UI卡頓。Unity的線程優先級又是怎樣的?
能否理解Unity Coroutine的迭代器本質,怎樣對Coroutine中的異常進行處理,如何使Coroutine具有返回值,Coroutine啟動時將分配多少內存,為什么復雜的Coroutine會使用更多的內存,如何將多個Coroutine合并為一個從而消除內存分配。
在與Native插件(如iOS插件)交互時,如何讓C#與Objective C或Java共享內存,從而減少大型數據封送造成的CPU負擔。
iOS平臺上AOT異常的根本原因是什么,有哪幾種。值類型和泛型的組合更容易引發AOT異常的原因是什么,如何繞過。怎么安全的使用Linq,使用C#標準事件為什么會觸發AOT異常,怎樣避免。Mono AOT的trampoline又是什么,哪種風格的代碼更容易耗盡trampoline并引發AOT異常。
Unity的C#編譯器有哪些弱點,哪些代碼通過Visual Studio編譯成DLL再放到Unity中可以提高執行效率和內存使用效率。
場景加載緩慢等Unity內部表現出來的問題如何從自身腳本下手進行優化。或者說不同性能問題在自己代碼中的Critical Path都是哪些部分。
渲染
Draw Call是什么。不同AssetBundle中的小圖片如何Batch到一個Draw Call中。
移動平臺常用的Tile-based GPU有哪些弱點,如何避免。
Retina等高清屏幕上制作2D游戲時,如何動態為圖片生成最小的Mesh網格以節約fill rate。
團隊協作
自己編寫Gameplay框架的情況下,如何控制隊友代碼中的內存泄漏。
使用版本管理系統時會產生哪些難以解決的沖突,如何建立開發規則。自己開發的框架或工具是否能有效避免隊友間發生沖突。
如何實現資源管線的自動化。
如何將各種奇葩動畫編輯器的輸出轉換成Unity標準的動畫資源。
制作編輯器擴展時,是否能正確序列化復雜的數據結構。能否讓自己的工具和腳本也實現所見即所得,讓隊友更快的搭建場景。
是否會使用Gizmo和Handle來擴展場景編輯器。
當不得不修改MonoBehaviour的定義時,怎樣讓已經上線的老版本中的數據正確地反序列化到新版本。
要有能力編寫模塊劃分明確,依賴關系合理清晰的可重用代碼和組件,作為公司的資產加速新項目的開發。
這些都是Unity開發中會不斷面對的問題,如果不能從始至終中控制住這些細節,積累起來往往會使團隊效率底下,難以產出高質量的應用。
所以我覺得Unity難以精通之處就在于對細節知識的把握,以及在整合團隊價值的過程中如何做到揚長避短。Unity開發團隊中常常不是所有人都會這個引擎有很深刻的認識,大家術業有專攻,有人搭場景,有人做后端,對自己不熟悉的領域,難免有錯誤的認知和實踐。我們尚可以通過時間和努力精通細節,然而到頭來真正缺少的,其實是團隊成員間的信任所帶來的溝通成本的降低。
【更新】
回答一些朋友的疑問。
關于資料來源
細節問題很難有系統的資料來源,而像AssetBundle Dynamic Batch這種幾乎找不到答案的問題只能自己慢慢摸索。在此列舉幾個最主要的知識來源。
官方手冊。例如搜索Unity Optimization可以找到官方在GPU,CPU和Mobile方面的幾篇優化手冊。官方資料常常包含最核心也最容易被忽略的原則,深入理解往往會有新的收獲。
官方博客。博客上不時會有一些技術類文章,如關于IL2CPP和序列化機制的知識幾乎只能看那幾篇博客。Technology
Unite的視頻和Slide。對某些領域有比較深入的探討,特別在內存管理,AssetBundle和代碼組織方面。YouTube和SlideShare上搜Unite或Unity能找到。值得注意的是Unite的分會場,如日本和韓國,有時會有一些更加深入的分析。如 slideshare.net 的頁面
Unity的Mono fork:Unity-Technologies/mono · GitHub ,關于GC和AOT方面是第一手的資料。比如gc的配置,Enumerable類的實現如何導致Linq容易觸發AOT異常,以及泛型CompareExchange中存在的JIT Hack導致C#事件和一些線程同步操作觸發AOT異常等等。另外GC方面也可以參考ivmai/bdwgc · GitHub ,有詳細的機制解釋。
UI的源代碼:Unity-Technologies / UI ,修改優化后可以直接集成到游戲中,很方便。
隨Unity安裝的PDB調試文件。Unity的安裝目錄下其實是有Editor和Player當中所有C++源碼的PDB文件的,而且居然都是private PDB。需要探查Unity內部數據結構和過程實現的時候,通過WinDbg配合這些PDB文件調試Unity進程可以獲得很多最底層的信息。當然,如果公司買了Unity的源碼就不必這樣麻煩了。
關于優化策略
不只是Unity,優化程序最重要的原則就是先測量。而且在沒有豐富經驗和自信的情況下,不要自己寫測量代碼,而要依賴Unity自己Profiler和Profiler API。這里只說一些Unity特有的內容。
使用Profiler時,切忌猜測。一定要弄清各種數據的精確涵義,如Self %,Self ms,GC Alloc等,如果弄不清楚,優化常常是南轅北轍。另外診斷CPU Spike時,一定要打開Deep Profile,否則只能看到誤導性很強的表面數據。找到真正的Hot Line才能著手優化改善性能。
當Hot Line在自己的代碼中時,可以嘗試將CPU密集的操作分派到后臺線程,然后在需要與Unity API交互時調度回來。粒度較好的操作可以嘗試用Coroutine分派到其他幀分別執行。大量GC Alloc造成的Spike需要重新設計內存分配策略,小對象(目前版本是小于1KB)較多的時候也可以嘗試預先擴大托管堆(如分配很多小于1KB的緩沖區,然后再釋放),這樣可以加速后續內存分配。因為Boehm GC的堆擴展策略是時間線性而非空間線性的,所以每次擴大后的容量都是翻倍的,需要注意。
而當Hot Line在Unity API中時,常常是自己的錯誤實踐造成的,需要重新審視設計。一方面要減少昂貴API的調用次數,一方面要降低Unity內部處理數據的規模。例如場景加載緩慢時,可能需要簡化場景本身,然后在場景啟動后再手動、增量地加載場景中的其他內容。
另外要了解一些底層知識。例如App啟動時性能較差的原因,在非AOT平臺上可能是因為大量的JIT編譯造成的,而在AOT平臺上則可能是因為初始化代碼過于復雜導致CPU緩存命中率很低,和操作系統頻繁地Page Fault。這也是為什么啟動代碼一定要精簡,并且要盡量實現批處理。
GPU方面,如果沒有復雜的特效,瓶頸常常在Draw Call和Fill Rate上。Draw Call需要Batch,能共享的材質一定要共享。Fill Rate的問題通常在高分辨率的2D游戲中比較明顯,Profiler中的Transparency渲染占比很大時就應該著手優化。GPU優化策略上Unity相比其他引擎并沒有很多特異的方面,準確測量的基礎上通常能找到比較通用的解決方法。
“游戲引擎Unity的入門知識點有哪些”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。