Unity3D學習(一):簡單梳理下Unity跨平臺的機制原理

前言編程

首先須要瞭解的是,Unity3D的C#基礎腳本模塊是經過Mono來實現的。c#

什麼是Mono?緩存

  參考下百度百科:Mono是一個由Novell公司(由Xamarin發起)主持的項目,並由Miguel de lcaza領導的,一個致力於開創.NET在Linux上使用的開源工程。它包含了一個C#語言的編譯器,一個CLR的Runtime,和一組類庫,並實現了 ADO NET和ASP NET。spa

  它基於CIL和C#的ECMA標準,提供了了微軟.Net FrameWork的另外一種實現。操作系統

 Mono主要有如下部分組成:翻譯

  C#編譯器——mcs。(最新的Mono版本已經能夠支持C#5.0,但Unity3D的Mono版本仍然停留在2.0+階段(支持c#3.0),因此C#的一些新功能沒法在unity中使用)接口

  運行時:即時編譯器JIT(後文會介紹)。以及GC,類庫加載器等等。開發

  基礎類庫(BCL)。get

  Mono類庫。提供了超出微軟.NET的一些類,提供了許多額外功能,主要是用於構建其餘操做系統上的應用。編譯器

下面進入正題:

Mono和Unity

Unity引擎自己是由C++寫出的,只不過Mono被嵌入到了Unity當中,爲unity提供了一個完整的虛擬機運行環境。這樣Mono的嵌入接口會將Mono Runtime暴露給Unity底層的C++代碼。經過這些接口,開發者就能夠控制Mono Runtime,以及依託於Mono Runtime的託管代碼。

Unity爲什麼可以跨平臺?

一句話歸納,主要緣由在於Unity經過Mono使用了一種叫CIL(Common Intermediate Language,也叫MSIL)通用中間語言的基於堆棧的代碼指令集,它屬於CLR的一個子集。

Unity3D的開發過程當中,代碼的編譯主要分爲兩個過程:

1)首先將對應的腳本代碼編譯成CIL(以後CIL還會被編譯成一種位元碼,生成一個CLI集合)。

2)而後Mono在運行時將CLI集合中的位元碼編譯爲本地運行的原生指令。(這裏會使用到上文中的JIT、AOT編譯模式)

注:也就是說在Mono中運行的實際上是CIL,而在本地運行的是被編譯後生成的原生指令。

這裏再提一下什麼是JIT和AOT

JIT:即時編譯,或者又稱爲動態編譯,是在程序執行時才編譯代碼,即將一條中間託管語句(CLI)翻譯成一條機器語句,而後執行這條語句。但它同時也會將編譯過的代碼進行緩存,而不是每一次都進行編譯。因此說它是靜態編譯和解釋器的結合體。

AOT:靜態編譯,一樣使用了JIT來進行編譯,只不過它在程序運行以前就編譯好了。但仍是有一部分代碼會即時編譯。

AOT的過程簡要:

1)收集須要編譯的代碼。

2)使用JIT編譯代碼。

3)發射編譯過的代碼和一些元數據

4)調用本地彙編器或鏈接器處理後生成可執行文件。

注:IOS平臺禁止使用JIT編譯器,因此Mono提供了一種FULL AOT模式,這裏不贅述。

總結

Unity的跨平臺,就是經過Mono將C#腳本代碼編譯成CLI,而後Mono運行時利用JIT或者AOT將CLI編譯成目標平臺的原生代碼實現的。

參考資料

  1.百度百科

  https://baike.baidu.com/item/CIL/3583850?fr=aladdin

  https://baike.baidu.com/item/JIT%E7%BC%96%E8%AF%91%E5%99%A8/3793585

  2.電子工業出版社:《Unity3D腳本編程》  做者:陳嘉棟

相關文章
相關標籤/搜索