Мои Уведомления
Привет, !
Мой Аккаунт Мои Финансы Мои Подписки Мои Настройки Выход
Руководство API скрипты

Unity предоставляет общий API сценариев и возможности для всех поддерживаемых платформ. Однако некоторые платформы имеют присущие ограничения. Чтобы помочь вам разобраться в этих ограничениях, в следующей таблице описано, какие ограничения применимы к каждой платформе и серверу сценариевфреймворку, поддерживающему сценарии в Unity. . Unity поддерживает три различных бэкэнда для сценариев в зависимости от целевой платформы: Mono, .NET и IL2CPP. Однако универсальная платформа Windows поддерживает только два: .NET и IL2CPP. Дополнительная информация
См. в Словарь
:

Среда выполнения сценариев, эквивалентная .NET 4.x

Платформа (серверная часть сценариев) Заблаговременная компиляция Нет тем Подмножество библиотек классов .NET Core
Android (IL2CPP)
Android (Mono)
iOSМобильная операционная система Apple. More info
See in Словарь
(IL2CPP)
Standalone (IL2CPP)
Standalone (Mono)
Universal Windows PlatformФункция IAP, поддерживающая симулятор Microsoft In App Purchase, который позволяет тестировать потоки покупок IAP на устройствах перед публикацией приложения. More info
See in Словарь
(IL2CPP)
Universal Windows Platform (.NET)
WebGLAPI JavaScript, который отображает 2D- и 3D-графику в веб-браузере. Вариант сборки Unity WebGL позволяет Unity публиковать контент в виде программ JavaScript, использующих технологии HTML5 и API рендеринга WebGL для запуска контента Unity в веб-браузере. More info
See in Словарь
(IL2CPP)

Заблаговременная компиляция

Некоторые платформы не позволяют генерировать код во время выполнения. Поэтому любой управляемый код, зависящий от JIT-компиляции на целевом устройстве, не будет работать. Вместо этого вы должны заранее скомпилировать весь управляемый код (AOT). Часто это различие не имеет значения, но в некоторых конкретных случаях платформы AOT требуют дополнительного рассмотрения.

System.Reflection.Emit

Платформа AOT не может реализовать ни один из методов в пространстве имен System.Reflection.Emit. Остальная часть System.Reflection приемлема, если компилятор может сделать вывод, что код, используемый посредством отражения, должен существовать во время выполнения.

Сериализация

Платформы AOT могут столкнуться с проблемами сериализации и десериализации из-за использования отражения. Если тип или метод используется только посредством отражения как часть сериализации или десериализации, компилятор AOT не может определить, что ему необходимо создать код, необходимый для типа или метода.

Общие виртуальные методы

Если вы используете универсальные методы, компилятор должен выполнить дополнительную работу, чтобы преобразовать ваш написанный код в код, исполняемый на устройстве. Например, вам нужен другой код для List с int или двойным. Если вы используете виртуальные методы, поведение которых определяется во время выполнения, а не во время компиляции, компилятор может легко потребовать генерации кода во время выполнения в тех местах, где это не совсем очевидно из исходного кода.

Следующий пример кода работает точно так, как ожидалось, на платформе JIT (он выводит на консоль сообщение «Message value: Zero» один раз):

using UnityEngine; using System; public class AOTProblemExample : MonoBehaviour, IReceiver { public enum AnyEnum { Zero, One, } void Start() { // Subtle trigger: The type of manager *must* be // IManager, not Manager, to trigger the AOT problem. IManager manager = new Manager(); manager.SendMessage(this, AnyEnum.Zero); } public void OnMessage(T value) { Debug.LogFormat("Message value: {0}", value); } } public class Manager : IManager { public void SendMessage(IReceiver target, T value) { target.OnMessage(value); } } public interface IReceiver { void OnMessage(T value); } public interface IManager { void SendMessage(IReceiver target, T value); }

Однако при выполнении этого кода на платформе AOT с IL2CPPразработанной в Unity серверной частью сценариев, которую вы можно использовать как альтернативу Mono при сборке проектов для некоторых платформ. Подробнее
См. в Словарь
серверной части скрипта, возникает это исключение:

ExecutionEngineException: Attempting to call method 'AOTProblemExample::OnMessage' for which no ahead of time (AOT) code was generated. at Manager.SendMessage[T] (IReceiver target, .T value) [0x00000] in :0 at AOTProblemExample.Start () [0x00000] in :0

Аналогичным образом бэкэнд сценариев Mono предоставляет подобное исключение:

ExecutionEngineException: Attempting to JIT compile method 'Manager:SendMessage (IReceiver,AOTProblemExample/AnyEnum)' while running with --aot-only. at AOTProblemExample.Start () [0x00000] in :0

Компилятор AOT не распознает необходимость генерировать код универсального метода OnMessage с T AnyEnum, поэтому он продолжается, пропуская этот метод. Когда этот метод вызывается, а среда выполнения не может найти правильный код для выполнения, она возвращает это сообщение об ошибке.

Чтобы решить проблему AOT, подобную этой, вы можете заставить компилятор генерировать правильный код. Для этого добавьте следующий пример метода в класс AOTProblemExample:

public void UsedOnlyForAOTCodeGeneration() { // IL2CPP needs only this line. OnMessage(AnyEnum.Zero); // Mono also needs this line. Note that we are // calling directly on the Manager, not the IManager interface. new Manager().SendMessage(null, AnyEnum.Zero); // Include an exception so we can be sure to know if this method is ever called. throw new InvalidOperationException("This method is used for AOT code generation only. Do not call it at runtime."); }

Когда компилятор встречает явный вызов OnMessage с T из AnyEnum, он генерирует правильный код для выполнения во время выполнения. Метод UsedOnlyForAOTCodeGeneration вызывать не нужно; он просто должен существовать, чтобы компилятор его распознал.

Вызов управляемых методов из машинного кода

Управляемые методы, которые необходимо маршалировать в указатель функции C, чтобы их можно было вызывать из машинного кода, имеют несколько ограничений на платформах AOT:

  • Управляемый метод должен быть статическим.
  • У управляемого метода должен быть атрибут [MonoPInvokeCallback]

Нет тем

Некоторые платформы не поддерживают использование потоков, поэтому любой управляемый код, использующий пространство имен System.Threading, дает сбой во время выполнения. Кроме того, некоторые части библиотек классов .NET неявно зависят от потоков. Часто используемым примером является класс System.Timers.Timer, который зависит от поддержки потоков.

Фильтры исключений

IL2CPP не поддерживает фильтры исключений C#. Вы должны изменить код, зависящий от фильтров исключений, в соответствующие блоки catch.

Типовая ссылка

IL2CPP не поддерживает тип System.TypedReference или ключевое слово C# __makeref.

Атрибуты MarshalAs и FieldOffset

IL2CPP не поддерживает отражение атрибутов MarhsalAs и FieldOffset во время выполнения. Он поддерживает эти атрибуты во время компиляции. Их следует использовать для правильной маршалинга вызовов платформы. .

Динамическое ключевое слово

IL2CPP не поддерживает ключевое слово C# dynamic. Это ключевое слово требует JIT-компиляции, что невозможно с IL2CPP.

Маршал.Предварительная ссылка

IL2CPP не поддерживает методы API Marshal.Prelink или Marshal.PrelinkAll.

Вы можете отблагодарить автора, за перевод документации на русский язык. ₽ Спасибо
Руководство Unity 2021.3