Отсутствие интерфейсов API .NET в Unity и UWP
При создании игры UWP с помощью .NET можно обнаружить, что некоторые API, которые можно использовать в редакторе Unity или для автономной игры на ПК, отсутствуют для UWP. Это связано с тем, что .NET для приложений UWP включает подмножество типов, предоставляемых в полной платформа .NET Framework для каждого пространства имен.
Кроме того, некоторые игровые механизмы используют различные вкусы .NET, которые не полностью совместимы с .NET для UWP, например Mono Unity. Поэтому при написании игры все может работать нормально в редакторе, но при переходе к сборке для UWP могут возникнуть такие ошибки: тип или пространство имен Formatters не существует в пространстве имен System.Runtime.Serialization (отсутствует ссылка на сборку?)
К счастью, Unity предоставляет некоторые из этих отсутствующих API в качестве методов расширения и типов замены, которые описаны в универсальная платформа Windows: отсутствующие типы .NET в серверной части скриптов .NET. Однако если вам нужная функциональность, обзор приложений .NET для Windows 8.x описывает способы преобразования кода в использование WinRT или .NET для среда выполнения Windows API. (Он также обсуждает Windows 8, но применимо к приложениям UWP для Windows 10.)
.NET Standard
Чтобы понять, почему некоторые API могут не работать, важно понять различные вкусы .NET и как UWP реализует .NET. .NET Standard — это официальная спецификация API .NET, которая должна быть кроссплатформенной и унифицировать различные вкусы .NET. Каждая реализация .NET поддерживает определенную версию .NET Standard. Вы можете просмотреть таблицу стандартов и реализаций в поддержке реализации .NET.
Каждая версия пакета SDK UWP соответствует другому уровню .NET Standard. Например, пакет SDK 16299 (Fall Creators Update) поддерживает .NET Standard 2.0.
Если вы хотите узнать, поддерживается ли определенный API .NET в целевой версии UWP, можно проверить ссылку на API .NET Standard и выбрать версию .NET Standard, поддерживаемую этой версией UWP.
Настройка серверной части скрипта
Первое, что необходимо сделать, если у вас возникли проблемы со сборкой для UWP, проверьте параметры проигрывателя (параметры сборки файлов>, выберите универсальная платформа Windows, а затем параметры проигрывателя). В разделе "Другие параметры > " первые три раскрывающихся списка (версия среды выполнения сценариев, серверная часть сценариев и уровень совместимости API) являются важными параметрами.
Версия среды выполнения сценариев — это то, что использует серверная часть скриптов Unity, которая позволяет получить (примерно) эквивалентную версию платформа .NET Framework поддержки, которую вы выбрали. Однако помните, что не все API-интерфейсы в этой версии платформа .NET Framework будут поддерживаться, только те, которые в версии .NET Standard предназначены для UWP.
Часто с новыми выпусками .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 будет работать.
Серверная часть скриптов может быть .NET или IL2CPP. В этой статье предполагается, что вы выбрали .NET, так как именно здесь возникают проблемы. Дополнительные сведения см. в разделе "Серверные серверы сценариев".
Наконец, необходимо задать уровень совместимости API для версии .NET, в которой должна выполняться игра. Это должно соответствовать версии среды выполнения сценариев.
Как правило, для версии среды выполнения сценариев и уровня совместимости API следует выбрать последнюю версию, чтобы обеспечить более совместимость с платформа .NET Framework и таким образом позволит использовать больше API .NET.
Компиляция, зависящая от платформы
Если вы создаете игру Unity для нескольких платформ, включая UWP, вы хотите использовать компиляцию, зависящую от платформы, чтобы убедиться, что код, предназначенный для UWP, выполняется только при создании игры в качестве UWP. Таким образом, вы можете использовать полную платформа .NET Framework для автономных настольных компьютеров и других платформ, а также API WinRT для UWP, не получая ошибок сборки.
Используйте следующие директивы, чтобы компилировать код только при выполнении в качестве приложения UWP:
#if NETFX_CORE
// Your UWP code here
#else
// Your standard code here
#endif
Примечание.
NETFX_CORE
предназначен только для проверки того, компилируется ли код C# в серверной части скриптов .NET. Если вы используете другую серверную часть сценариев, например IL2CPP, используйте вместо этого ENABLE_WINMD_SUPPORT .
Распространенные проблемы и обходные решения для них
В следующих сценариях описываются распространенные проблемы, которые могут возникнуть, когда API .NET отсутствуют в подмножестве UWP и способы их обхода.
Сериализация данных с помощью BinaryFormatter
Обычно игры сериализуют данные, чтобы игроки не могли легко управлять им. Однако BinaryFormatter, который сериализует объект в двоичный файл, недоступен в более ранних версиях .NET Standard (до 2.0). Вместо этого рекомендуется использовать XmlSerializer или 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();
}
Операции ввода-вывода
Некоторые типы в пространстве имен System.IO , например FileStream, недоступны в более ранних версиях .NET Standard. Однако Unity предоставляет типы каталогов, файлов и файлов, чтобы их можно было использовать в игре.
Кроме того, можно использовать API-интерфейсы Windows.Storage , которые доступны только приложениям 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, недоступны при создании игры Unity для UWP. В этих случаях используйте 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
}
Дополнительные сведения об использовании API безопасности WinRT см. в статье "Безопасность ".
Сеть
Некоторые из System.Net.* пространства имен, такие как System.Net.Mail, также недоступны при создании игры Unity для UWP. Для большинства этих API используйте соответствующие интерфейсы Windows.Networking.* и Windows.Web.* API WinRT для получения аналогичных функций. Дополнительные сведения см. в разделе "Сети и веб-службы ".
В случае System.Net.Mail используйте пространство имен Windows.ApplicationModel.Email . Дополнительные сведения см. в статье "Отправка электронной почты ".