Unity-腳本限制
我們致力于在 Unity 支持的所有平臺之間提供通用的腳本 API 和體驗。但是,有些平臺存在固有的限制。為幫助您了解這些限制并支持跨平臺代碼,下表描述了每個平臺和腳本后端適用的限制:

.NET 3.5 等效腳本運行時
警告:此功能已棄用,不應(yīng)再使用。請使用 .NET 4。

提前編譯
有些平臺不允許生成運行時代碼。因此,任何依賴于在目標設(shè)備上即時 (JIT) 編譯的托管代碼都將失敗。相反,我們需要提前 (AOT) 編譯所有托管代碼。通常,這種區(qū)別并不重要,但在少數(shù)特定情況下,AOT 平臺需要額外注意。
System.Reflection.Emit
AOT 平臺無法實現(xiàn)?System.Reflection.Emit?命名空間中的任何方法。請注意,System.Reflection?的其余部分是可接受的,只要編譯器可以推斷通過反射使用的代碼需要在運行時存在。
序列化
AOT 平臺可能會由于使用了反射而遇到序列化和反序列化問題。如果僅通過反射將某個類型或方法作為序列化或反序列化的一部分使用,則 AOT 編譯器無法檢測到需要為該類型或方法生成代碼。
通用虛擬方法
通用方法要求編譯器做一些額外的工作,將開發(fā)人員編寫的代碼擴展到設(shè)備上實際執(zhí)行的代碼。例如,對于具有?int?或?double?類型的?List,我們需要不同代碼。虛擬方法在運行時而不是編譯時確定行為,存在虛擬方法時,編譯器可在不完全明顯的地方輕松地要求從源代碼生成運行時代碼。
假設(shè)有以下代碼,此代碼在 JIT 平臺上完全按預(yù)期工作(向控制臺輸出一次“Message value: Zero”):
使用 IL2CPP 腳本后端在 AOT 平臺上執(zhí)行此代碼時,發(fā)生以下異常:
同樣,Mono 腳本后端提供以下類似的異常:
?
AOT 編譯器不會意識到自己應(yīng)該為?T?為?AnyEnum?的泛型方法?OnMessage?生成代碼,所以它直接繼續(xù)往下,跳過該方法。調(diào)用該方法時,運行時無法找到要執(zhí)行的正確代碼,因此拋出此錯誤消息。
要解決像這樣的 AOT 問題,我們通??梢詮娭凭幾g器為我們生成適當?shù)拇a。如果我們向?AOTProblemExample?類添加如下所示的方法:
當編譯器遇到?T?為?AnyEnum?的?OnMessage?的顯式調(diào)用時,它會生成運行時執(zhí)行的正確代碼。不需要調(diào)用?UsedOnlyForAOTCodeGeneration?方法;該方法的存在只是為了讓編譯器看到而已。
無線程
有些平臺不支持使用線程,因此任何使用?System.Threading?命名空間的托管代碼都將在運行時失敗。此外,.NET 類庫的某些部分存在對線程的隱式依賴。一個常用的例子是?System.Timers.Timer?類,它依賴于對線程的支持。