API .NET mancanti in Unity e UWP

Quando si compila un gioco UWP con .NET, è possibile che alcune API che potresti usare nell'editor unity o per un gioco per PC autonomo non siano presenti per la piattaforma UWP. Ciò è dovuto al fatto che .NET per le app UWP include un subset dei tipi forniti in .NET Framework completo per ogni spazio dei nomi.

Inoltre, alcuni motori di gioco usano diversi tipi di .NET che non sono completamente compatibili con .NET per UWP, ad esempio Mono di Unity. Quindi, quando scrivi il tuo gioco, tutto potrebbe funzionare correttamente nell'editor, ma quando vai a compilare per la piattaforma UWP, potresti ricevere errori come questo: Il tipo o lo spazio dei nomi 'Formattatori' non esiste nello spazio dei nomi 'System.Runtime.Serialization' (manca un riferimento all'assembly?)

Fortunatamente, Unity fornisce alcune di queste API mancanti come metodi di estensione e tipi di sostituzione, descritti in piattaforma UWP (Universal Windows Platform): Tipi .NET mancanti nel back-end di scripting .NET. Tuttavia, se la funzionalità necessaria non è disponibile, .NET per le app di Windows 8.x illustra i modi in cui è possibile convertire il codice per usare WinRT o .NET per le API di Windows Runtime. Illustra Windows 8, ma è applicabile anche alle app UWP di Windows 10.

.NET Standard

Per capire perché alcune API potrebbero non funzionare, è importante comprendere i diversi tipi di .NET e come la piattaforma UWP implementa .NET. .NET Standard è una specifica formale delle API .NET progettate per essere multipiattaforma e unificare le diverse versioni di .NET. Ogni implementazione di .NET supporta una determinata versione di .NET Standard. È possibile visualizzare una tabella di standard e implementazioni nel supporto dell'implementazione di .NET.

Ogni versione di UWP SDK è conforme a un livello diverso di .NET Standard. Ad esempio, 16299 SDK (Fall Creators Update) supporta .NET Standard 2.0.

Se vuoi sapere se una determinata API .NET è supportata nella versione UWP di destinazione, puoi controllare le informazioni di riferimento sulle API .NET Standard e selezionare la versione di .NET Standard supportata da tale versione di UWP.

Configurazione back-end di scripting

La prima cosa da fare se hai problemi di compilazione per UWP è controllare il player Impostazioni (Impostazioni > di compilazione file, seleziona piattaforma UWP (Universal Windows Platform) e quindi Player Impostazioni). In Altro Impostazioni > Configurazione, i primi tre elenchi a discesa (Versione del runtime di scripting, Back-end di scripting e Livello di compatibilità API) sono tutte impostazioni importanti da considerare.

La versione del runtime di scripting è l'uso del back-end di script di Unity che consente di ottenere la versione (approssimativamente) equivalente di .NET Framework scelta. Tenere tuttavia presente che non tutte le API in tale versione di .NET Framework saranno supportate, ma solo quelle nella versione di .NET Standard di destinazione della piattaforma UWP.

Spesso con le nuove versioni di .NET vengono aggiunte altre API a .NET Standard, che potrebbero consentire di usare lo stesso codice in modalità autonoma e UWP. Ad esempio, lo spazio dei nomi System.Runtime.Serialization.Json è stato introdotto in .NET Standard 2.0. Se si imposta la versione del runtime di scripting su .NET 3.5 Equivalent (destinata a una versione precedente di .NET Standard), si riceverà un errore quando si tenta di usare l'API. Passare a .NET 4.6 Equivalent (che supporta .NET Standard 2.0) e l'API funzionerà.

Il back-end di scripting può essere .NET o IL2CPP. Per questo argomento si presuppone che tu abbia scelto .NET, perché è qui che si verificano i problemi illustrati qui. Vedere Scripting Backends per maggiori informazioni.

Infine, devi impostare il livello di compatibilità api sulla versione di .NET in cui vuoi che il gioco venga eseguito. Deve corrispondere alla versione del runtime di scripting.

In generale, per La versione del runtime di script e il livello di compatibilità api, è consigliabile selezionare la versione più recente disponibile in modo da avere maggiore compatibilità con .NET Framework e quindi consentire di usare più API .NET.

Configuration: Scripting Runtime Version; Scripting Backend; Api Compatibility Level

Compilazione dipendente dalla piattaforma

Se stai creando il tuo gioco Unity per più piattaforme, inclusa la piattaforma UWP, dovrai usare la compilazione dipendente dalla piattaforma per assicurarti che il codice destinato alla piattaforma UWP venga eseguito solo quando il gioco viene compilato come piattaforma UWP. In questo modo, è possibile usare .NET Framework completo per desktop autonomo e altre piattaforme e api WinRT per UWP, senza ricevere errori di compilazione.

Usare le direttive seguenti per compilare il codice solo quando viene eseguito come app UWP:

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

Nota

NETFX_CORE è progettato solo per verificare se si sta compilando codice C# nel back-end di scripting .NET. Se si usa un back-end di scripting diverso, ad esempio IL2CPP, usare invece ENABLE_WINMD_SUPPORT .

Problemi comuni e soluzioni alternative

Gli scenari seguenti descrivono i problemi comuni che possono verificarsi quando mancano le API .NET nel sottoinsieme UWP e i modi per aggirarli.

Serializzazione dei dati con BinaryFormatter

È comune che i giochi serializzino i dati di salvataggio in modo che i giocatori non possano modificarli facilmente. Tuttavia, BinaryFormatter, che serializza un oggetto in formato binario, non è disponibile nelle versioni precedenti di .NET Standard (prima della versione 2.0). Prendere in considerazione l'uso di XmlSerializer o DataContractJsonSerializer .

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

Operazioni I/O

Alcuni tipi nello spazio dei nomi System.IO , ad esempio FileStream, non sono disponibili nelle versioni precedenti di .NET Standard. Unity fornisce tuttavia i tipi Directory, File e FileStream in modo da poterli usare nel gioco.

In alternativa, è possibile usare Windows.Archiviazione API, disponibili solo per le app UWP. Tuttavia, queste API limitano l'app a scrivere nella propria risorsa di archiviazione specifica e non concedere l'accesso gratuito all'intero file system. Per altre informazioni, vedere File e cartelle e librerie.

Una nota importante è che il metodo Close è disponibile solo in .NET Standard 2.0 e versioni successive (anche se Unity fornisce un metodo di estensione). In alternativa, usare Dispose .

Threading

Alcuni tipi nello spazio dei nomi System.Threading , ad esempio ThreadPool, non sono disponibili nelle versioni precedenti di .NET Standard. In questi casi, è invece possibile usare lo spazio dei nomi Windows.System.Threading .

Ecco come gestire il threading in un gioco Unity, usando la compilazione dipendente dalla piattaforma per prepararsi per le piattaforme UWP e non UWP:

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

Sicurezza

Alcuni dei sistemi System.Security.* gli spazi dei nomi, ad esempio System.Security.Cryptography.X509Certificates, non sono disponibili quando si compila un gioco Unity per UWP. In questi casi, usare Windows.Security.* API, che coprono gran parte delle stesse funzionalità.

L'esempio seguente ottiene semplicemente i certificati da un archivio certificati con il nome specificato:

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
    }

Per altre informazioni sull'uso delle API di sicurezza di WinRT, vedere Sicurezza .

Rete

Alcuni dei System.Net.* gli spazi dei nomi, ad esempio System.Net.Mail, non sono disponibili anche durante la creazione di un gioco Unity per la piattaforma UWP. Per la maggior parte di queste API, usare il corrispondente Windows.Networking.* e Windows.Web.* API WinRT per ottenere funzionalità simili. Per altre informazioni, vedere Servizi di rete e Web.

Nel caso di System.Net.Mail, usare lo spazio dei nomi Windows.ApplicationModel.Email. Per ulteriori informazioni, vedere Ivia email.

Vedi anche