Unity框架設(shè)計:跨平臺底層如何處理C#代碼
在面試中,我們經(jīng)常會被問到Unity的底層是如何處理C#,本節(jié)給通過一下3個點來給大家詳細(xì)的分析這個問題:
(1) C#的發(fā)展歷史;
(2) Unity為什么用C#;
(3) il2cpp解決了什么問題;
?
C#的發(fā)展歷史
?
C#沒有出來之前,當(dāng)時Java憑借Java虛擬機+Java字節(jié)碼解釋執(zhí)行,讓Java代碼移植編寫可以跨平臺運行。同時Java等有了垃圾回收機制等,大大的降低了開發(fā)的難度。微軟為了應(yīng)對Java, 推出了.net平臺。.net平臺包含了幾個點:
a: 設(shè)計創(chuàng)造一些編程開發(fā)語言,比如: C#, J#等。
b: .net開發(fā)工具,將.net 這些編程語言編譯成.net字節(jié)碼,我們叫做 CLR或IL,這樣C#編寫的代碼可以被J#調(diào)用的到,因為底層都是基于.net字節(jié)碼。
c: 開發(fā)一個.net 虛擬機能解釋執(zhí)行CLR字節(jié)碼,同時把.net虛擬機移植到多個平臺(windows, win mobile等windows系的操作系統(tǒng))。這樣用C#/J#開發(fā)的程序能跨平臺到.net支持的操作系統(tǒng)上,同時C#, J#底層一樣,能相互的調(diào)用。
d: 為了讓.net能支持更多的平臺,微軟把.net CLR的標(biāo)準(zhǔn)開放出來了。
e: 出了一個開源的項目Mono, 以.net為標(biāo)準(zhǔn),開發(fā)出了支持主流的PC與移動操作系統(tǒng)的.net 虛擬機。這樣使得.net代碼有機會能運行到非win家族系列的操作系統(tǒng)上。
?
Unity為什么用C#
?
講完.net的發(fā)展歷史的幾個階段以后,我們來看下為什么Unity會使用選C#來做開發(fā)語言。Unity 出來的時候,也需要解決 游戲 for mac, 游戲for linux, 游戲for windows, 游戲 for xbox等平臺,后來手游發(fā)展起來以后又要解決 游戲 for Android, 游戲for IOS等。所以Unity引擎必須要構(gòu)建在能跨平臺發(fā)布的這個基礎(chǔ)上。所以早期的Unity選擇了Mono,作為跨平臺基礎(chǔ),所以Unity是基于mono發(fā)展起來的項目。而mono 基于.net技術(shù)構(gòu)建,所以在mono上開發(fā),可以支持多種開發(fā)語言,c#, J#等所以早期Unity能支持C#, Boo, Js等編程語言,都是基于mono .net技術(shù)。所以Mono幫助Unity解決了跨平臺問題,開發(fā)語言與開發(fā)工具的問題。
看上去一切很美好,但是基于mono構(gòu)建的技術(shù)方案也有致命的問題,后期的Unity發(fā)現(xiàn)問題越來越多,主要的問題如下:
a: 程序執(zhí)行效率,在移動端解釋執(zhí)行CLR代碼,終歸效率不如直接的native代碼;
b: Mono虛擬機移植,當(dāng)一個新的游戲開發(fā)平臺出來以后,又要重新移植mono虛擬機,這里產(chǎn)生的bug先不說,能不能支持出來還不一定;
c: mono版權(quán)問題,當(dāng)Unity使用mono的時候,需要mono的授權(quán);
d: mono 虛擬機要移植到 web平臺幾乎不可能,而現(xiàn)在web平臺也非常的流行,比如微信抖音小游戲等;
e: IOS不允許運行.net 虛擬機;
?
Unity il2cpp?救世主
?
為了解決mono .net的問題,Unity 開發(fā)團隊推出了一個新的技術(shù),就是il2cpp,顧名思義就是講CLR/IL代碼通過il2cpp,把它轉(zhuǎn)成c/c++代碼,然后再基于平臺的native開發(fā)工具再進(jìn)行編譯,最終編譯出native的二進(jìn)制代碼。
同時C#這些高級編程語言會有一些高級特性,比如垃圾回收等,這樣就需要在底層做一些支撐,比如基于C/C++實現(xiàn)垃圾回收, C#的線程庫等。這些功能都實現(xiàn)到il2cpp runtime庫(il2cpp vm)上,運行的時候來提供這些基礎(chǔ)服務(wù)的支撐。
這樣做發(fā)布IOS沒有任何問題,native code性能也好,同時如果有新的平臺出現(xiàn)的時候,只要把C/C++移植到對應(yīng)的平臺就可以了,移植的時候非常的方便。
總結(jié)一下unity基于il2cpp 來構(gòu)建處理C#的基本原理與步驟:
(1) 開發(fā)者還是基于.net的C#來進(jìn)行開發(fā);
(2) 還是使用.net的工具將C#的代碼編譯成CLR or IL
(3) 使用il2cpp工具,將CLR/IL字節(jié)碼轉(zhuǎn)成靜態(tài)的C++代碼;
(4) 使用native的開發(fā)工具(xcode, Android NDK等),來將C++代碼編譯成目標(biāo)的native機器碼;
這樣Unity開發(fā)到目標(biāo)OS平臺的安裝包就打包發(fā)布出來了。假設(shè)有新的平臺出現(xiàn)后,只要將游戲引擎的native代碼+平臺工程工具移植好就可以了,獲得更好性能的同時獲得了更好的跨平臺移植性。最后上一個圖來展示一下整個的架構(gòu),如下:
?

本節(jié)就分享到這里了,關(guān)注我,學(xué)習(xí)更多的Unity開發(fā)的知識。
Unity / 精選推薦
字節(jié)跳動面試題:Unity底層如何處理C#
https://www.bycwedu.com/promotion_channels/1636278015