API de .NET que faltan en Unity y UWP
Al compilar un juego para UWP con .NET, puedes encontrar que algunas API que puedes usar en el editor de Unity o para un juego de PC independiente no están presentes para UWP. Esto se debe a que .NET para aplicaciones para UWP incluye un subconjunto de los tipos proporcionados en .NET Framework completo para cada espacio de nombres.
Además, algunos motores de juegos usan diferentes tipos de .NET que no son totalmente compatibles con .NET para UWP, como Mono de Unity. Por lo tanto, cuando escribes tu juego, todo podría funcionar bien en el editor, pero cuando vayas a la compilación para UWP, podrías obtener errores como este: El tipo o el espacio de nombres 'Formatters' no existe en el espacio de nombres 'System.Runtime.Serialization' (¿falta una referencia de ensamblado?)
Afortunadamente, Unity proporciona algunas de estas API que faltan como métodos de extensión y tipos de reemplazo, que se describen en Plataforma universal de Windows: Faltan tipos de .NET en el back-end de scripting de .NET. Sin embargo, si la funcionalidad que necesita no está aquí, en .NET para aplicaciones de Windows 8.x se describen las formas en que puede convertir el código para usar las API de WinRT o .NET para Windows Runtime. (Describe Windows 8, pero también es aplicable a las aplicaciones para UWP de Windows 10).
.NET Standard
Para comprender por qué es posible que algunas API no funcionen, es importante comprender los diferentes tipos de .NET y cómo implementa UWP .NET. .NET Standard es una especificación formal de las API de .NET diseñadas para ser multiplataforma y unificar los diferentes tipos de .NET. Cada implementación de .NET admite una determinada versión de .NET Standard. Puede ver una tabla de estándares e implementaciones en compatibilidad con la implementación de .NET.
Cada versión del SDK de UWP se ajusta a un nivel diferente de .NET Standard. Por ejemplo, el SDK 16299 (Fall Creators Update) admite .NET Standard 2.0.
Si quieres saber si se admite una determinada API de .NET en la versión de UWP que tienes como destino, puedes comprobar la referencia de API de .NET Standard y seleccionar la versión de .NET Standard compatible con esa versión de UWP.
Configuración de back-end de scripting
Lo primero que debes hacer si tienes problemas para compilar para UWP es comprobar la configuración del reproductor (Configuración de compilación de archivos>, seleccionar Plataforma universal de Windows y, a continuación, Configuración del reproductor). En Otras opciones de configuración>, las tres primeras listas desplegables (versión del entorno de ejecución de scripting, back-end de scripting y nivel de compatibilidad de api) son todas las opciones importantes que se deben tener en cuenta.
La versión del entorno de ejecución de scripting es lo que usa el back-end de scripting de Unity que permite obtener la versión equivalente (aproximadamente) de compatibilidad con .NET Framework que elija. Sin embargo, ten en cuenta que no se admitirán todas las API de esa versión de .NET Framework, solo las de la versión de .NET Standard a la que se dirige tu UWP.
A menudo con las nuevas versiones de .NET, se agregan más API a .NET Standard, lo que podría permitirle usar el mismo código en UWP y independiente. Por ejemplo, el espacio de nombres System.Runtime.Serialization.Json se introdujo en .NET Standard 2.0. Si establece la versión del entorno de ejecución de scripting en equivalente de .NET 3.5 (que tiene como destino una versión anterior de .NET Standard), obtendrá un error al intentar usar la API; cambiarla a equivalente a .NET 4.6 (que admite .NET Standard 2.0) y la API funcionará.
El back-end de scripting puede ser .NET o IL2CPP. En este tema, se supone que ha elegido .NET, ya que es donde surgen los problemas que se describen aquí. Consulte Scripting Backends (Scripts de back-end) para obtener más información.
Por último, debes establecer el nivel de compatibilidad de API en la versión de .NET en la que quieres que se ejecute el juego. Esto debe coincidir con la versión del entorno de ejecución de scripting.
En general, en El nivel de compatibilidad de API y versión del entorno de ejecución de scripting, debe seleccionar la versión más reciente disponible para tener más compatibilidad con .NET Framework y, por tanto, permitirle usar más API de .NET.
Compilación dependiente de la plataforma
Si vas a compilar tu juego de Unity para varias plataformas, incluida UWP, querrás usar la compilación dependiente de la plataforma para asegurarte de que el código diseñado para UWP solo se ejecuta cuando el juego se compila como UWP. De este modo, puedes usar la versión completa de .NET Framework para escritorio independiente y otras plataformas, y las API de WinRT para UWP, sin obtener errores de compilación.
Use las siguientes directivas para compilar código solo cuando se ejecuta como una aplicación para UWP:
#if NETFX_CORE
// Your UWP code here
#else
// Your standard code here
#endif
Nota:
NETFX_CORE
solo está pensado para comprobar si está compilando código de C# en el back-end de scripting de .NET. Si usa un back-end de scripting diferente, como IL2CPP, use ENABLE_WINMD_SUPPORT en su lugar.
Problemas comunes y soluciones alternativas
En los escenarios siguientes se describen los problemas comunes que pueden surgir en los que faltan las API de .NET del subconjunto de UWP y formas de solucionarlos.
Serialización de datos mediante BinaryFormatter
Es habitual que los juegos serialicen los datos para que los jugadores no puedan manipularlos fácilmente. Sin embargo, BinaryFormatter, que serializa un objeto en binario, no está disponible en versiones anteriores de .NET Standard (antes de la versión 2.0). Considere la posibilidad de usar XmlSerializer o DataContractJsonSerializer en su lugar.
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();
}
Operaciones de E/S
Algunos tipos del espacio de nombres System.IO , como FileStream, no están disponibles en versiones anteriores de .NET Standard. Sin embargo, Unity proporciona los tipos Directory, File y FileStream para que puedas usarlos en tu juego.
Como alternativa, puedes usar las API de Windows.Storage , que solo están disponibles para las aplicaciones para UWP. Sin embargo, estas API restringen la aplicación a escribir en su almacenamiento específico y no le conceden acceso gratuito a todo el sistema de archivos. Consulte Archivos, carpetas y bibliotecas para obtener más información.
Una nota importante es que el método Close solo está disponible en .NET Standard 2.0 y versiones posteriores (aunque Unity proporciona un método de extensión). Use Dispose en su lugar.
Subprocesamiento
Algunos tipos de espacios de nombres System.Threading , como ThreadPool, no están disponibles en versiones anteriores de .NET Standard. En estos casos, puede usar el espacio de nombres Windows.System.Threading en su lugar.
Así es como podrías controlar el subproceso en un juego de Unity, usando la compilación dependiente de la plataforma para prepararte tanto para plataformas para UWP como para plataformas que no sean para UWP:
private void UsingThreads()
{
#if NETFX_CORE
Windows.System.Threading.ThreadPool.RunAsync(workItem => SomeMethod());
#else
System.Threading.ThreadPool.QueueUserWorkItem(workItem => SomeMethod());
#endif
}
Seguridad
Parte de System.Security.* Los espacios de nombres, como System.Security.Cryptography.X509Certificates, no están disponibles al compilar un juego de Unity para UWP. En estos casos, use Windows.Security.* API, que cubren gran parte de la misma funcionalidad.
En el ejemplo siguiente simplemente se obtienen los certificados de un almacén de certificados con el nombre especificado:
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
}
Consulte Seguridad para obtener más información sobre el uso de las API de seguridad de WinRT.
Redes
Algunos de los System.Net.* Los espacios de nombres, como System.Net.Mail, tampoco están disponibles al compilar un juego de Unity para UWP. Para la mayoría de estas API, use las correspondientes Windows.Networking.* y Windows.Web.* API de WinRT para obtener una funcionalidad similar. Consulte Redes y servicios web para obtener más información.
En el caso de System.Net.Mail, use el espacio de nombres Windows.ApplicationModel.Email . Consulte Enviar correo electrónico para obtener más información.