Udostępnij za pomocą


Brak interfejsów API .NET w silnikach Unity i platformie UWP

Podczas kompilowania gry UWP przy użyciu .NET może się okazać, że niektóre interfejsy API, które mogą być używane w edytorze Unity lub w samodzielnej grze na PC, nie są dostępne w UWP. To dlatego, że .NET dla aplikacji UWP zawiera podzbiór typów oferowanych przez pełne środowisko .NET Framework dla każdej przestrzeni nazw.

Ponadto niektóre silniki gier używają różnych odmian platformy .NET, które nie są w pełni zgodne z .NET dla UWP, takich jak Mono używane przez Unity. Więc podczas pisania gry wszystko może działać dobrze w edytorze, ale po przejściu do kompilacji dla platformy UWP mogą wystąpić błędy takie jak: Typ lub przestrzeń nazw "Formatery" nie istnieje w przestrzeni nazw "System.Runtime.Serialization" (czy brakuje odwołania do zestawu?)

Na szczęście Unity udostępnia niektóre z tych brakujących interfejsów API jako metody rozszerzeń i typy zastępcze, które opisano w Universal Windows Platform: brakujące typy .NET dla zaplecza skryptów .NET w. Jeśli jednak wymagana funkcjonalność nie jest tutaj dostępna, w sekcji "Omówienie platformy .NET dla aplikacji Windows 8.x" omawia się sposoby konwersji kodu na użycie środowiska WinRT lub .NET dla interfejsów API środowiska uruchomieniowego Windows. (Omówiono w nim system Windows 8, ale ma zastosowanie również do aplikacji platformy UWP systemu Windows 10).

.NET Standard

Aby zrozumieć, dlaczego niektóre interfejsy API mogą nie działać, ważne jest, aby zapoznać się z różnymi wersjami .NET i sposobem, w jaki UWP implementuje .NET. .NET Standard to formalna specyfikacja interfejsów API platformy .NET, której celem jest być międzyplatformową i ujednolicić różne wersje platformy .NET. Każda implementacja platformy .NET obsługuje określoną wersję platformy .NET Standard. Tabelę standardów i implementacji można znaleźć w sekcji wsparcie implementacji .NET.

Każda wersja zestawu SDK platformy UWP jest zgodna z innym poziomem platformy .NET Standard. Na przykład zestaw SDK 16299 (aktualizacja Fall Creators Update) obsługuje platformę .NET Standard 2.0.

Jeśli chcesz wiedzieć, czy określony interfejs API platformy .NET jest obsługiwany w docelowej wersji platformy UWP, możesz sprawdzić .NET Standard API Reference i wybrać wersję platformy .NET Standard obsługiwaną przez tę wersję platformy UWP.

Konfiguracja zaplecza skryptów

Pierwszą czynnością, którą należy wykonać, jeśli masz problem z kompilacją dla UWP, jest sprawdzenie ustawień odtwarzacza Player Settings (Ustawienia plików > Kompilacji, wybierz pozycję Platforma uniwersalna systemu Windows, a następnie Ustawienia odtwarzacza). W obszarze Inne ustawienia > Konfiguracjapierwsze trzy listy rozwijane (wersja środowiska uruchomieniowego skryptów, Backend skryptówi poziom zgodności interfejsu API) są ważnymi ustawieniami, które należy wziąć pod uwagę.

Wersja środowiska uruchomieniowego skryptów jest wykorzystywana przez backend skryptowy Unity i umożliwia uzyskanie wersji programu .NET Framework równoważnej (lub mniej więcej równoważnej) tej, którą wybierzesz. Należy jednak pamiętać, że nie wszystkie interfejsy API w tej wersji .NET Framework będą obsługiwane, a jedynie te w wersji .NET Standard, która jest celem Twojego UWP.

Często w przypadku nowych wersji .NET więcej interfejsów API jest dodawanych do .NET Standard, co może umożliwić korzystanie z tego samego kodu w aplikacjach autonomicznych i UWP. Na przykład przestrzeń nazw System.Runtime.Serialization.Json została wprowadzona w wersji .NET Standard 2.0. Jeśli ustawisz wersję środowiska uruchomieniowego skryptu na .NET 3.5 Równoważne (która jest przeznaczona dla wcześniejszej wersji platformy .NET Standard), podczas próby użycia interfejsu API zostanie wyświetlony błąd; przełącz go na .NET 4.6 Równoważna (która obsługuje platformę .NET Standard 2.0), a interfejs API będzie działać.

zaplecze skryptów może być .NET lub IL2CPP. W tym temacie przyjęto założenie, że wybrano .NET, ponieważ w tym miejscu pojawiają się problemy omówione w tym miejscu. Aby uzyskać więcej informacji, zobacz Backend skryptów.

Na koniec należy ustawić poziom zgodności interfejsu API na wersję platformy .NET, na którą ma działać twoja gra. Powinno to być zgodne z wersją środowiska uruchomieniowego skryptów .

Ogólnie rzecz biorąc, w przypadku wersji środowiska uruchomieniowego skryptów i poziomu zgodności interfejsu API należy wybrać najnowszą dostępną wersję, aby zapewnić większą zgodność z programem .NET Framework, a tym samym umożliwić korzystanie z większej liczby interfejsów API platformy .NET.

konfiguracja : wersja środowiska uruchomieniowego skryptów; Backend skryptowy; poziom zgodności interfejsu API

Kompilacja zależna od platformy

Jeśli tworzysz grę w Unity dla wielu platform, w tym UWP, powinieneś użyć kompilacji zależnej od używanej platformy, aby upewnić się, że kod przeznaczony dla UWP jest uruchamiany tylko gdy gra jest kompilowana jako UWP. W ten sposób można użyć pełnego programu .NET Framework dla autonomicznych komputerów stacjonarnych i innych platform oraz interfejsów API WinRT dla platformy UWP bez uzyskiwania błędów kompilacji.

Użyj następujących dyrektyw, aby skompilować kod tylko podczas uruchamiania jako aplikacja platformy UWP:

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

Uwaga / Notatka

NETFX_CORE jest przeznaczona tylko do sprawdzenia, czy kompilujesz kod języka C# względem zaplecza skryptów platformy .NET. Jeśli używasz innego zaplecza skryptów, takiego jak IL2CPP, użyj ENABLE_WINMD_SUPPORT zamiast tego.

Typowe problemy i ich rozwiązania

W poniższych scenariuszach opisano typowe problemy, które mogą wystąpić, gdy w podzestawie platformy UWP brakuje interfejsów API platformy .NET oraz sposoby ich obejścia.

Serializacja danych przy użyciu klasy BinaryFormatter

Często zdarza się, że gry serializują zapisywanie danych, dzięki czemu gracze nie mogą łatwo manipulować nimi. Jednak BinaryFormatter, który serializuje obiekt do formatu binarnego, nie jest dostępny we wcześniejszych wersjach standardu .NET (przed 2.0). Rozważ użycie XmlSerializer lub 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();
}

Operacje we/wy

Niektóre typy w przestrzeni nazw System.IO, takie jak FileStream, nie są dostępne we wcześniejszych wersjach platformy .NET Standard. Jednak Unity udostępnia typy Directory, Filei FileStream, dzięki czemu można ich używać w grze.

Alternatywnie możesz użyć interfejsów API Windows.Storage, które są dostępne tylko dla aplikacji platformy UWP. Jednak te interfejsy API ograniczają aplikację do zapisywania w określonej pamięci i nie zapewniają jej swobodnego dostępu do całego systemu plików. Aby uzyskać więcej informacji, zobacz Pliki, foldery i biblioteki.

Należy pamiętać, że metoda Close jest dostępna tylko na platformie .NET Standard 2.0 lub nowszej (chociaż Unity udostępnia metodę rozszerzenia). Zamiast tego użyj Dispose.

Wątkowanie

Niektóre typy w przestrzeniach nazw System.Threading, takich jak ThreadPool, nie są dostępne we wcześniejszych wersjach platformy .NET Standard. W takich przypadkach można zamiast tego użyć Windows.System.Threading przestrzeni nazw.

Poniżej przedstawiono sposób obsługi wątków w grze Unity, używając kompilacji zależnej od platformy, aby przygotować ją zarówno dla platformy UWP, jak i dla innych platform.

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

Bezpieczeństwo

Niektóre z System.Security.* przestrzenie nazw, takie jak System.Security.Cryptography.X509Certificates, nie są dostępne podczas tworzenia gry Unity na platformie UWP. W takich przypadkach należy użyć interfejsów Windows.Security.*, które zapewniają większość tej samej funkcjonalności.

Poniższy przykład po prostu pobiera certyfikaty z magazynu certyfikatów o podanej nazwie:

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
    }

Aby uzyskać więcej informacji na temat korzystania z interfejsów API zabezpieczeń WinRT, zobacz Security.

Networkowanie

Niektóre przestrzenie nazw System.Net.*, takie jak System.Net.Mail, również nie są dostępne przy tworzeniu gry w Unity na platformie UWP. W przypadku większości tych interfejsów API użyj odpowiedniego Windows.Networking.* i Windows.Web.* Interfejsu API WinRT, aby uzyskać podobną funkcjonalność. Aby uzyskać więcej informacji, zobacz Sieci i usługi internetowe.

W przypadku System.Net.Mailużyj przestrzeni nazw Windows.ApplicationModel.Email. Aby uzyskać więcej informacji, zobacz Wyślij wiadomość e-mail.

Zobacz także