unity的c#腳本和標準的c#語言有什麼區別和聯繫?unity是僅僅使用了c#的語法嗎?


這個問題可以從Unity支持的.NET標準和實現細節兩個角度看。

從對.NET標準支持的角度看,這只是一個版本的問題。Unity的 .NET Runtime版本是2.0,支持的 .NET Profile是3.5,默認的C#語言版本是4.0。這和你用Visual Studio 2017把語言版本降到4.0,寫一個3.5的庫是一樣的,區別只是在於版本比較落後,很多 .NET 4.x 的新功能不能用。

其他主流的 .NET 實現有傳統的 .NET Framework ,跨平台移動開發用的Xamarin/Mono和跨平台的 .NET Core。這三種實現相對比較統一,支持4.0的Runtime,4.6的庫和C# 7。自從去年加入了 .NET Foundation Technical Steering Group,Unity也在努力向最新標準靠攏,現在微軟的Xamarin團隊正在和Unity一起做這個事情。這個過程中最重要的里程碑就是即將到來的 .NET Standard 2.0,其發布之後包括Unity在內的主流 .NET 實現都會支持這一標準,這樣一來在 .NET 標準層面上Unity就真的和其他 .NET 實現沒有區別了。

不過從實現細節上看,Unity和其他 .NET 實現相比還是有短時間內難以彌補的差距。主要原因是Unity的技術架構比較複雜,又有很強的跨平台需求,所以升級起來比較困難。Unity Scripting的技術架構從下到上主要有三個部分:

1. C++編寫的引擎內核,Unity絕大部分核心功能都在這一層實現。

2. IL2CPP,一個AOT的runtime實現,提供 .NET 執行引擎和GC等服務。Unity從Mono遷移到IL2CPP的主要動力主要是相比於不停修改Mono,基於C++的工具鏈更容易將runtime移植到新的平台上。

3. 基於Mono嵌入技術的用戶腳本。Unity相當於在一個C++寫的native程序中內嵌了一個Mono環境,包含引擎核心功能的native API以UnityEngine.dll這樣的形式封裝起來提供給Mono腳本調用。而腳本實際上被編譯成一個普通的 .NET assembly,Unity載入以後根據需要調用和執行。

另外除了用戶自己寫的C#腳本,Unity編輯器的大部分UI和UnityEngine.UI.dll也是以用戶腳本的形式在這一層實現的。

Unity跟其他 .NET 實現的主要差距是在runtime性能和工具支持方面。首先是build pipeline,即使Unity支持了 .NET Standard 2.0,可能也沒法短時間內把編譯器換成Roslyn,意味著不能第一時間用上C# 7。主要原因是Roslyn生成的debug符號跟mono差別比較大,debug引擎需要做相應的修改。其次缺少對NuGet的支持也讓Unity比較難融入 .NET 生態系統,Unity的Project系統和包管理系統都很薄弱,詭異的pipeline想要支持NuGet需要很大的改動,微軟方面也要配合才行。Unity內部也才開始討論這個問題,並沒有明確的方案,能實現估計要相當長時間。

Runtime方面也不樂觀,首當其衝的就是GC。Unity想要換一個更好更適合C#的GC,難度主要在於複雜的執行環境,Unity需要在native環境下操縱託管環境下的腳本對象,想支持GC分代回收和移動對象位置,這部分還是有很多工作需要做。然而如果不把Boehm GC換掉,升級 .NET Profile的意義就變得很微妙,.NET和C#的很多設計都基於對GC性能的信心,比如async/await,沒有一個好GC,用起來還是會束手束腳。

也許很快我們就會有一個支持最新 .NET 標準的Unity了,然而其在開發體驗和性能方面還是會長時間落後於其他 .NET實現。希望這期間不要被別的引擎幹掉就好。


u3d的c#是一個特定版本的c#語法,符合那個版本的標準。(其實就是2.0包含一部分3.0語法和核心組件)標準的c#語言大概是指語言協會的c#標準了。現在的版本是7.0。

c#本身作為一個語言也只有語法詞法這些語言相關的規定吧。至於backend rutime gc compiler這些都是看各家實現的。只是這個語言有個最大的玩家就是微軟,然而微軟當年也沒能讓c#很火。反倒是這麼棒的語言讓u3d這種同人給玩火了。


目前這個星球上有常見的兩個C#引擎,

  • 一個是Xamarin的Mono(開源的)
  • 一個是微軟的 .net framework。

你所說的標準C#,應該是指微軟的 .net framework里的吧,它目前暫時只能Windows運行(未來不是)。

Unity中,則使用的是開源的Mono引擎,是跨平台的,Windows、Linux都行。

除了不同的引擎,C#還有版本之分。

比如說,Java有Java 6, Java 7, Java 8;C#也有分C# 5.0 , C# 6.0等不同版本,每個版本都有一些新的語法特性。

Mono引擎的開發,理論上是嚴格的向微軟的C#兼容的。語言層面上應用起來,沒有多大的區別。

所以,要討論語法區別的細節,還要知道,哪個Mono的版本,跟哪個 .net framework C#的版本做比較....

Unity 5.4之前,使用基於Mono 2.x版本的Unity特製版。這個版本相當於 微軟 .net framework 3.5版本里的C#.......

因此,Unity的C#腳本,有很多的特性是沒有實現的。

好消息時,Unity 5.5之後,官方開始更新它們的Mono引擎了,像async/await的語法特性,也逐漸被支持了。

題外話,微軟正在實施開源戰略,.net framework會在未來更開放,其核心部分分出了 .net core庫,而 .net core 可能會在未來也成為Mono的底層一部分。

如果你想更深入了解,可以上StackOverflow上看更深入的技術差異。比如這些:

What『s the difference between .NET Core, .NET Framework, and Xamarin?


unity3d的c#代碼只是習慣性的被叫做腳本,用起來和c#一樣。現在unity用的是c#4和不完整的dotnet3.5,運行時實現是第三方的mono和自己的li2cpp。區別就是語法不是最新的,庫支持不是最完整的,其他用起來不會有區別。官方說以後會支持最新的c#,值得期待。


Unity 2017.3已經開始支持.Net4.6 Framwork ,不過這是實驗性質的,對應C#版本應該是5.0以上.


推薦閱讀:

學習Unity3D有什麼比較好的資料嘛?
unity在ios平台下內存的優化?
C#如何向C++生成的dll文件中傳遞二維數組?
零基礎學unity3d需要培訓么?
如何用unity做兩面互相反射的鏡子?

TAG:Unity遊戲引擎 |