Unity引擎編譯後的程序是如何運行在iOS和Android上的?

不是很系統的了解這裡的原理。請了解的朋友解答一下。


@vczh 雖然沒有具體說細節,但是大體的概念是對的。

平台/系統之間的差異總是要有人通過開發中間層來吸收,關鍵只是在於誰來做這個工作而已。

目前來說Unity Player的組成大概是UnityEngine + Mono運行時。

UnityEngine提供的是引擎的底層功能,這部分基本是C++實現的。每個目標平台有自己的平台依存代碼,每種圖形API各自有一個渲染器。(也就是說,基本上每個平台要有一個版本)

Mono(Home | Mono)運行時則是提供了一個跨平台的CLR實現,允許引擎和用戶的託管代碼運行在每一個目標平台上。Mono自身在開發的時候就是跨平台的,實際上也是對大部分支持的處理器架構分別實現了JIT/AOT引擎。(由於Unity現在支持的平台數大於他們使用的Mono版本,很多後端是Unity自己實現/調整過的)

所以Unity的多平台部署,基本就是用戶的託管代碼(平台無關)+針對目標平台的Mono運行時+針對目標平台的UnityEngine。用戶生成的託管代碼(.net Assembly)會在運行時被對應平台的Mono運行時JIT執行。

而Unity對Mono-AOT的利用,目前主要是針對iOS之類不允許運行時生成Native Code的平台,算是一個針對平台安全策略的Workaround。

當然Unity的多平台支持也不是僅僅把編譯後的Assembly和Player打個包那麼簡單,因為對於遊戲還有藝術資產的問題。

舉例來說,每個平台可能有自己原生支持的音頻格式、紋理格式等等。對於這些差異Unity在打包的過程中也會自行吸收掉。所以雖然很多用戶看到的多平台發布體驗基本上就是簡單的右鍵另存為,但背後Unity還是做了不少工作。

維護十幾二十個平台的Mono運行時是個相當麻煩的工作,外加Unity使用的Mono版本老舊,無法支持新的.net特性,性能也不盡人意。因此在未來Unity將會逐步開始引入新的運行時IL2CPP,最終替代大部分平台上的Mono Runtime。(目前已經用在了Unity 5.0的WebGL平台上)

IL2CPP會將CIL編譯成C++,然後通過平台SDK的C++編譯器編譯成對應平台上的原生代碼。(至少按照Unity內部測試的結果是這樣的)有興趣的可以參考這篇官方Blog:The future of scripting in Unity,以及Unite 2014的相關Session:https://www.youtube.com/watch?v=Bfa9ILwlsFw(youtube注意)

第一次回答,如果內容有任何問題歡迎指出……


技術上看,關鍵點大致就是這些:

1. mono實現了基本的CLI庫,和.net的編譯環境。這樣用戶編寫的.net代碼可以直接編譯成平台無關的bytecode

2. 針對具體平台,unity通過P/Invoke的方式實現了一系列專有類和介面函數,用來訪問平台特定的資源。

3. 對於每一個平台,unity提供了一個應用的外殼,用來封裝和引導以bytecode形式存在的用戶代碼。用戶可以直接發布封裝好的應用。

其實跨平台的基本原理並不複雜,主要難度還是針對具體平台的實施和優化。


簡單來講,他在ios和android上各實現了一次。你的程序想發布到什麼平台,你是要先export一下的,然後他會幫你盡量AOT成目標平台需要的指令集。


c#的話

http://www.mono-project.com

而unity惡搞的JavaScript是可以編譯的


推薦閱讀:

遊戲程序員入門應該從Unity3D或Cocos2dx開始,還是從OpenGL和DirectX開始?
DirectX和OpenGL如何抉擇?
unity3d里的Surface shader中的surf,LightingName,finalColor,到底屬於渲染管線的哪個階段?
「渲染地球」引擎實現的原理可能是什麼?
《Manifold Garden》中的模型描邊是怎麼實現的?

TAG:Unity遊戲引擎 |