這個問題可以從Unity支持的.NET標準和實現(xiàn)細節(jié)兩個角度看汤求。
?從對 .NET?標準支持的角度看畅哑,這只是一個版本的問題肴楷。
Unity的 .NET Runtime 版本是 2.0,支持的? .NET Profile 是3.5敢课,默認的 C# 語言版本是 4.0阶祭。
這和你用 Visual Studio 2017 把語言版本降到 4.0,寫一個 3.5 的庫是一樣的直秆,區(qū)別只是在于版本比較落后濒募,很多 .NET 4.x 的新功能不能用。
其他主流的 .NET 實現(xiàn)有傳統(tǒng)的 .NET Framework 圾结,跨平臺移動開發(fā)用的Xamarin/Mono和跨平臺的 .NET Core瑰剃。
這三種實現(xiàn)相對比較統(tǒng)一,支持4.0的 Runtime筝野,4.6 的庫和 C# 7晌姚。自從去年加入了 .NET Foundation Technical Steering Group,Unity也在努力向最新標準靠攏歇竟,現(xiàn)在微軟的Xamarin團隊正在和Unity一起做這個事情挥唠。
這個過程中最重要的里程碑就是即將到來的 .NET Standard 2.0,其發(fā)布之后包括Unity在內(nèi)的主流 .NET 實現(xiàn)都會支持這一標準焕议,這樣一來在 .NET 標準層面上Unity就真的和其他 .NET 實現(xiàn)沒有區(qū)別了宝磨。
在實現(xiàn)細節(jié)上,Unity和其他 .NET 實現(xiàn)相比還是有短時間內(nèi)難以彌補的差距。主要原因是Unity的技術架構比較復雜唤锉,又有很強的跨平臺需求世囊,所以升級起來比較困難。Unity Scripting的技術架構從下到上主要有三個部分:
1. C++ 編寫的引擎內(nèi)核窿祥,Unity 絕大部分核心功能都在這一層實現(xiàn)株憾。
2. IL2CPP,一個 AOT 的runtime實現(xiàn)晒衩,提供 .NET 執(zhí)行引擎和 GC等服務嗤瞎。Unity 從Mono 遷移到 IL2CPP的主要動力主要是相比于不停修改 Mono,基于 C++的工具鏈更容易將 runtime移植到新的平臺上浸遗。
3. 基于 Mono嵌入技術的用戶腳本猫胁。Unity相當于在一個C++寫的native程序中內(nèi)嵌了一個 Mono環(huán)境,包含引擎核心功能的 native API以UnityEngine.dll這樣的形式封裝起來提供給 Mono腳本調(diào)用跛锌。而腳本實際上被編譯成一個普通的 .NET assembly弃秆,Unity加載以后根據(jù)需要調(diào)用和執(zhí)行。
另外除了用戶自己寫的 C#腳本髓帽,Unity 編輯器的大部分 UI和 UnityEngine.UI.dll也是以用戶腳本的形式在這一層實現(xiàn)的菠赚。
Unity 跟其他 .NET 實現(xiàn)的主要差距是在runtime性能和工具支持方面。首先是build pipeline郑藏,即使Unity支持了 .NET Standard 2.0衡查,可能也沒法短時間內(nèi)把編譯器換成Roslyn,意味著不能第一時間用上 C# 7必盖。主要原因是Roslyn生成的debug符號跟mono差別比較大拌牲,debug 引擎需要做相應的修改。其次缺少對NuGet的支持也讓Unity比較難融入 .NET 生態(tài)系統(tǒng)歌粥,Unity 的Project 系統(tǒng)和包管理系統(tǒng)都很薄弱塌忽,詭異的pipeline想要支持NuGet 需要很大的改動,微軟方面也要配合才行失驶。Unity 內(nèi)部也才開始討論這個問題土居,并沒有明確的方案,能實現(xiàn)估計要相當長時間嬉探。
Runtime 方面也不樂觀擦耀,首當其沖的就是 GC。Unity 想要換一個更好更適合 C#的? GC涩堤,難度主要在于復雜的執(zhí)行環(huán)境眷蜓,Unity 需要在 native環(huán)境下操縱托管環(huán)境下的腳本對象,想支持 GC分代回收和移動對象位置胎围,這部分還是有很多工作需要做吁系。然而如果不把 Boehm GC換掉芹敌,升級 .NET Profile的意義就變得很微妙,.NET和 C#的很多設計都基于對 GC性能的信心垮抗,比如async/await,沒有一個好 GC碧聪,用起來還是會束手束腳冒版。
也許很快我們就會有一個支持最新 .NET 標準的 Unity了,然而其在開發(fā)體驗和性能方面還是會長時間落后于其他 .NET實現(xiàn)逞姿。希望這期間不要被別的引擎干掉就好辞嗡。