共用方式為


Unity 和 UWP 中遺漏 .NET API

使用 .NET 建置 UWP 遊戲時,您可能會發現在 Unity 編輯器或獨立計算機遊戲中可能用於 UWP 的某些 API 不存在。 這是因為適用於 UWP 應用程式的 .NET 包含每個命名空間的完整 .NET Framework 中所提供的類型子集。

此外,某些遊戲引擎會使用與UWP的 .NET 完全不相容的不同 .NET 類型,例如 Unity 的 Mono。 因此,當您撰寫遊戲時,所有專案在編輯器中可能都運行正常,但當您開始為 UWP 進行建置時,可能會遇到以下錯誤: 命名空間 'System.Runtime.Serialization' 中不存在類型或命名空間 'Formatters' (是否缺少組件參考?)

幸運的是,Unity 提供了一些缺失的 API 作為擴充方法和替代類型,詳情請參閱《通用 Windows 平台:.NET 腳本後端中的缺失 .NET 類型》。 不過,如果您需要的功能不在這裡,適用於 Windows 8.x 應用程式的 .NET 概觀 討論如何將程式碼轉換成使用 WinRT 或 .NET for Windows 執行階段 API 的方式。 (它討論 Windows 8,但也適用於 Windows 10 UWP app。

.NET Standard

若要瞭解某些 API 可能無法運作的原因,請務必瞭解不同的 .NET 類別,以及 UWP 如何實作 .NET。 .NET Standard 是 .NET API 的正式規格,旨在跨平臺,並統一不同的 .NET 類別。 .NET 的每個實作都支援特定版本的 .NET Standard。 您可以在 .NET 實作支援看到標準和實作的數據表。

每個 UWP SDK 版本都符合不同層級的 .NET Standard。 例如,16299 SDK (Fall Creators Update) 支援 .NET Standard 2.0。

如果您想要知道目標 UWP 版本中是否支援特定 .NET API,您可以檢查 .NET Standard API 參考,然後選取該版本 UWP 所支援的 .NET Standard 版本。

編寫後端組態的腳本

如果您在建置 UWP 時遇到問題,首先要做的是檢查 Player Settings[檔案] > [建置設定],選取 [通用 Windows 平臺],然後 [播放器設定]]。 在 [其他設定 > 組態下,前三個下拉式清單(腳本運行時間版本腳本後端API 兼容性層級)都是需要考慮的重要設定。

腳本運行時間版本 是 Unity 腳本後端所使用的功能,可讓您取得您選擇的 .NET Framework 支援 (大致) 對等版本。 不過,請記住,並非該版本的 .NET Framework 中的所有 API 都會被支援,只有那些符合您 UWP 所目標的 .NET Standard 版本的 API 才會被支援。

使用新的 .NET 版本時,通常會將更多 API 新增至 .NET Standard,這可讓您跨獨立和 UWP 使用相同的程式代碼。 例如,System.Runtime.Serialization.Json 命名空間是在 .NET Standard 2.0 中引進的。 如果您將 腳本運行時間版本 設定為 .NET 3.5 對等(以舊版 .NET Standard 為目標),則嘗試使用 API 時會收到錯誤:將它切換至 .NET 4.6 對等(支援 .NET Standard 2.0),API 將會運作。

腳本後端 可以 .NETIL2CPP。 針對本主題,我們假設您已選擇 .NET,因為這是此處討論的問題所在。 如需詳細資訊,請參閱 腳本後端

最後,您應該將 Api 相容性層級 設定為您想要讓遊戲執行的 .NET 版本。 這應該符合 腳本執行時間版本

一般而言,針對 腳本運行時間版本Api 相容性層級,您應該選取可用的最新版本,以便與 .NET Framework 產生更多相容性,因此可讓您使用更多 .NET API。

組態:腳本運行時間版本;編寫後端腳本;API 相容性層級

平臺相依編譯

如果您要為多個平臺建置 Unity 遊戲,包括 UWP,您會想要使用平臺相依編譯,以確保只有在遊戲建置為 UWP 時,才會執行適用於 UWP 的程式代碼。 如此一來,您就可以針對獨立桌面和其他平臺使用完整的 .NET Framework,以及適用於UWP的 WinRT API,而不會收到建置錯誤。

使用下列指示詞,只在以 UWP 應用程式的形式執行時編譯程式代碼:

#if NETFX_CORE
    // Your UWP code here
#else
    // Your standard code here
#endif

備註

NETFX_CORE 只是為了檢查您是否要針對 .NET 腳本後端編譯 C# 程序代碼。 如果您使用不同的腳本後端,例如 IL2CPP,請改用 ENABLE_WINMD_SUPPORT

常見問題和因應措施

下列案例描述 UWP 子集遺漏 .NET API 的常見問題,以及解決它們的方式。

使用 BinaryFormatter 進行數據串行化

遊戲通常會串行化儲存數據,讓玩家無法輕易地操作數據。 不過,將物件序列化為二進位的 BinaryFormatter,無法在早期版本的 .NET Standard (2.0 之前) 中使用。 請考慮改用 XmlSerializerDataContractJsonSerializer

private void Save()
{
    SaveData data = new SaveData(); // User-defined object to serialize

    DataContractJsonSerializer serializer = 
      new DataContractJsonSerializer(typeof(SaveData));

    FileStream stream = 
      new FileStream(Application.persistentDataPath, FileMode.CreateNew);

    serializer.WriteObject(stream, data);
    stream.Dispose();
}

I/O 作業

System.IO 命名空間中的某些類型,例如 FileStream,無法在舊版的 .NET Standard 中使用。 不過,Unity 提供 DirectoryFileFileStream 類型,讓您可以在遊戲中使用這些類型。

或者,您可以使用 Windows.Storage API,而 API 僅適用於 UWP 應用程式。 不過,這些 API 會將應用程式限制為寫入其特定記憶體,而不會給予應用程式整個檔案系統的免費存取權。 如需詳細資訊,請參閱 檔案、資料夾和連結庫

其中一個重要注意事項是,Close 方法僅適用於 .NET Standard 2.0 和更新版本(雖然 Unity 提供擴充方法)。 請改用 Dispose

線程

System.Threading 命名空間中的某些類型,例如 ThreadPool,無法在舊版的 .NET Standard 中使用。 在這些情況下,您可以改用 Windows.System.Threading 命名空間。

以下說明如何在 Unity 遊戲中處理線程,使用平臺相依編譯來準備 UWP 和非 UWP 平臺:

private void UsingThreads()
{
#if NETFX_CORE
    Windows.System.Threading.ThreadPool.RunAsync(workItem => SomeMethod());
#else
    System.Threading.ThreadPool.QueueUserWorkItem(workItem => SomeMethod());
#endif
}

安全

某些 System.Security。* 命名空間,例如 System.Security.Cryptography.X509Certificates,當您為 UWP 建置 Unity 遊戲時無法使用。 在這些情況下,請使用 Windows.Security。* API,其中涵蓋許多相同的功能。

下列範例只會從具有指定名稱的證書存儲取得憑證:

private async void GetCertificatesAsync(string certStoreName)
    {
#if NETFX_CORE
        IReadOnlyList<Certificate> certs = await CertificateStores.FindAllAsync();
        IEnumerable<Certificate> myCerts = 
            certs.Where((certificate) => certificate.StoreName == certStoreName);
#else
        X509Store store = new X509Store(certStoreName, StoreLocation.CurrentUser);
        store.Open(OpenFlags.OpenExistingOnly);
        X509Certificate2Collection certs = store.Certificates;
#endif
    }

如需使用 WinRT 安全性 API 的詳細資訊,請參閱 安全性

網路

一些 System.Net。* 命名空間,例如 System.Net.Mail,在建置適用於 UWP 的 Unity 遊戲時也無法使用。 針對大部分的這些 API,請使用對應的 Windows.Networking.* 和 Windows.Web.* WinRT API 以取得類似的功能。 如需詳細資訊,請參閱 網路和Web服務

System.Net.Mail時,請使用 Windows.ApplicationModel.Email 命名空間。 如需詳細資訊,請參閱 傳送電子郵件

另請參閱