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