API .NET manquantes dans Unity et UWP

Lorsque vous créez un jeu UWP à l’aide de .NET, vous pouvez constater que certaines API que vous pouvez utiliser dans l’éditeur Unity ou pour un jeu PC autonome ne sont pas présentes pour UWP. En effet, .NET pour les applications UWP inclut un sous-ensemble des types fournis dans le .NET Framework complet pour chaque espace de noms.

En outre, certains moteurs de jeu utilisent différentes versions de .NET qui ne sont pas entièrement compatibles avec .NET pour UWP, comme mono d’Unity. Par conséquent, lorsque vous écrivez votre jeu, tout peut fonctionner correctement dans l’éditeur, mais lorsque vous accédez à la génération pour UWP, vous pouvez obtenir des erreurs telles que : Le type ou l’espace de noms « Formateurs » n’existe pas dans l’espace de noms « System.Runtime.Serialization » (il manque une référence d’assembly ?)

Heureusement, Unity fournit certaines de ces API manquantes en tant que méthodes d’extension et types de remplacement, qui sont décrits dans plateforme Windows universelle : Types .NET manquants sur le serveur principal de script .NET. Toutefois, si la fonctionnalité dont vous avez besoin n’est pas ici, la vue d’ensemble des applications .NET pour Windows 8.x explique comment convertir votre code pour utiliser WinRT ou .NET pour Windows Runtime API. (Il traite des Windows 8, mais s’applique également aux applications UWP Windows 10.)

.NET Standard

Pour comprendre pourquoi certaines API peuvent ne pas fonctionner, il est important de comprendre les différentes saveurs .NET et la façon dont UWP implémente .NET. . NET Standard est une spécification formelle des API .NET qui est destinée à être multiplateforme et à unifier les différentes saveurs .NET. Chaque implémentation de .NET prend en charge une certaine version de .NET Standard. Vous pouvez voir un tableau des normes et des implémentations dans prise en charge de l’implémentation .NET.

Chaque version du KIT de développement logiciel (SDK) UWP est conforme à un niveau différent de .NET Standard. Par exemple, le Kit de développement logiciel (SDK) 16299 (Fall Creators Update) prend en charge .NET Standard 2.0.

Si vous souhaitez savoir si une certaine API .NET est prise en charge dans la version UWP que vous ciblez, vous pouvez case activée la référence de l’API .NET Standard et sélectionner la version de .NET Standard prise en charge par cette version d’UWP.

Configuration du back-end de script

La première chose que vous devez faire si vous rencontrez des problèmes de génération pour UWP est case activée paramètres du lecteur (Paramètres de build de fichier>, sélectionnez plateforme Windows universelle, puis Paramètres du lecteur). Sous Autres paramètres > Configuration, les trois premières listes déroulantes (Version du runtime de script, Serveur principal de script et Niveau de compatibilité de l’API) sont toutes des paramètres importants à prendre en compte.

La version du runtime de script est ce que le back-end de script Unity utilise, ce qui vous permet d’obtenir la version (à peu près) équivalente de la prise en charge du .NET Framework que vous choisissez. Toutefois, gardez à l’esprit que toutes les API de cette version du .NET Framework ne seront pas prises en charge, uniquement celles de la version de .NET Standard que votre UWP cible.

Souvent, avec les nouvelles versions de .NET, d’autres API sont ajoutées à .NET Standard, ce qui peut vous permettre d’utiliser le même code entre les versions autonomes et UWP. Par exemple, l’espace de noms System.Runtime.Serialization.Json a été introduit dans .NET Standard 2.0. Si vous définissez la version du runtime de script sur .NET 3.5 Equivalent (qui cible une version antérieure de .NET Standard), vous obtiendrez une erreur lors de la tentative d’utilisation de l’API ; basculez-le vers .NET 4.6 Équivalent (qui prend en charge .NET Standard 2.0), et l’API fonctionnera.

Le serveur principal de script peut être .NET ou IL2CPP. Pour cette rubrique, nous partons du principe que vous avez choisi .NET, car c’est là que se posent les problèmes abordés ici. Pour plus d’informations, consultez Scripting Backends .

Enfin, vous devez définir le niveau de compatibilité de l’API sur la version de .NET sur laquelle vous souhaitez que votre jeu s’exécute. Cela doit correspondre à la version du runtime de script.

En général, pour la version du runtime de script et le niveau de compatibilité de l’API, vous devez sélectionner la dernière version disponible afin d’avoir plus de compatibilité avec le .NET Framework et ainsi vous permettre d’utiliser davantage d’API .NET.

Configuration : Version du runtime de script ; Scripting Backend ; Niveau de compatibilité de l’API

Compilation dépendante de la plateforme

Si vous créez votre jeu Unity pour plusieurs plateformes, y compris UWP, vous devez utiliser la compilation dépendante de la plateforme pour vous assurer que le code destiné à UWP n’est exécuté que lorsque le jeu est généré en tant qu’UWP. De cette façon, vous pouvez utiliser le .NET Framework complet pour les plateformes de bureau autonomes et autres, ainsi que les API WinRT pour UWP, sans obtenir d’erreurs de build.

Utilisez les directives suivantes pour compiler du code uniquement lors de l’exécution en tant qu’application UWP :

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

Notes

NETFX_COREest uniquement destiné à case activée si vous compilez du code C# sur le back-end de script .NET. Si vous utilisez un autre back-end de script, tel qu’IL2CPP, utilisez ENABLE_WINMD_SUPPORT à la place.

Problèmes courants et solutions de contournement

Les scénarios suivants décrivent les problèmes courants qui peuvent se produire lorsque les API .NET sont manquantes dans le sous-ensemble UWP et les moyens de les contourner.

Sérialisation des données à l’aide de BinaryFormatter

Il est courant que les jeux sérialisent les données d’enregistrement afin que les joueurs ne puissent pas les manipuler facilement. Toutefois, BinaryFormatter, qui sérialise un objet en binaire, n’est pas disponible dans les versions antérieures de .NET Standard (antérieures à la version 2.0). Envisagez d’utiliser XmlSerializer ou DataContractJsonSerializer à la place.

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();
}

opérations d'E/S

Certains types dans l’espace de noms System.IO , tels que FileStream, ne sont pas disponibles dans les versions antérieures de .NET Standard. Toutefois, Unity fournit les types Répertoire, Fichier et FileStream afin que vous puissiez les utiliser dans votre jeu.

Vous pouvez également utiliser les API Windows.Storage , qui ne sont disponibles que pour les applications UWP. Toutefois, ces API limitent l’écriture de l’application dans leur stockage spécifique et ne lui donnent pas un accès gratuit à l’ensemble du système de fichiers. Pour plus d’informations , consultez Fichiers, dossiers et bibliothèques .

Notez que la méthode Close n’est disponible que dans .NET Standard 2.0 et versions ultérieures (bien que Unity fournisse une méthode d’extension). Utilisez Disposer à la place.

Thread

Certains types dans les espaces de noms System.Threading , tels que ThreadPool, ne sont pas disponibles dans les versions antérieures de .NET Standard. Dans ce cas, vous pouvez utiliser l’espace de noms Windows.System.Threading à la place.

Voici comment gérer le threading dans un jeu Unity, en utilisant la compilation dépendante de la plateforme pour préparer les plateformes UWP et non-UWP :

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

Sécurité

Certains des System.Security. * Les espaces de noms, tels que System.Security.Cryptography.X509Certificates, ne sont pas disponibles lorsque vous créez un jeu Unity pour UWP. Dans ce cas, utilisez Windows.Security. * API, qui couvrent la plupart des mêmes fonctionnalités.

L’exemple suivant obtient simplement les certificats d’un magasin de certificats portant le nom donné :

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
    }

Pour plus d’informations sur l’utilisation des API de sécurité WinRT, consultez Sécurité .

Mise en réseau

Certains des System.Net. * Les espaces de noms, tels que System.Net.Mail, ne sont pas non plus disponibles lors de la création d’un jeu Unity pour UWP. Pour la plupart de ces API, utilisez le Windows.Networking correspondant. * et Windows.Web. * API WinRT pour obtenir des fonctionnalités similaires. Pour plus d’informations, consultez Mise en réseau et services web .

Dans le cas de System.Net.Mail, utilisez l’espace de noms Windows.ApplicationModel.Email. Pour plus d’informations, consultez Envoyer un e-mail .

Voir aussi