Android плагин для unity

Building and using plug-ins for Android

You can use plug-ins developed for Android to call Java and C++ code created outside of Unity from your C# scripts A piece of code that allows you to create your own Components, trigger game events, modify Component properties over time and respond to user input in any way you like. More info
See in Glossary . This allows you to access features like OS calls and third-party code libraries that would otherwise not be available to Unity. For more information about using plug-ins with Unity, see documentation on plug-ins A set of code created outside of Unity that creates functionality in Unity. There are two kinds of plug-ins you can use in Unity: Managed plug-ins (managed .NET assemblies created with tools like Visual Studio) and Native plug-ins (platform-specific native code libraries). More info
See in Glossary .

The pages in this section describe the process of creating your own plug-ins for use in Android projects. The information on these pages assumes you already know how to create native plug-ins for Unity. For more information about native plug-ins and their uses, see documentation on native plug-ins A platform-specific native code library that is created outside of Unity for use in Unity. Allows you can access features like OS calls and third-party code libraries that would otherwise not be available to Unity. More info
See in Glossary .

This section contains the following pages:

Unity as a Library

If you upgrade your project to Unity 2019.4 or above, the introduction of Unity as a Library might require you to adapt your native and managed plug-ins to work properly for Android.

Источник

Сборка плагинов для Android

На этой странице описан нативный код плагинов для Android.

Сборка плагина для Android

Чтобы построить плагин для Android, вы должны сначала получить Android NDK и ознакомиться с инструкцией по созданию общей библиотеки.

Если вы используете C++ (.cpp), при создании плагина вы должны убедиться, что функции объявлены с C-связями, чтобы избежать проблем с коверканьем имен.

Использование вашего плагина из C

После сборки, общая библиотека должна быть скопированы в папку Assets->Plugins->Android . Unity будет искать её по имени, когда вы определяете функцию вроде следующей в C#-скрипте:-

Обратите внимание, что PluginName не должно включать ни префикс (‘Lib’), ни расширение (‘.so’). Вы должны обернуть все нативные методы кода дополнительным слоем C#-кода. Этот код должен проверить Application.platform и вызывать собственные методы только тогда, когда приложение работает на реальном устройстве; фиктивные значения могут быть возвращены из С#-кода при работе в редакторе. Вы также можете использовать определения платформы для контроля зависимости компиляции кода от платформы.

Проекты библиотек для Android

Вы можете закинуть проекты прекомпилированной Android библиотеки в папку Assets->Plugins->Android . Прекомпилированная — значит все .java файлы должны быть скомпилированы в jar файлы, расположенные либо в папке bin/, либо в папке libs/ проекта. AndroidManifest.xml из этих папок будет автоматически объединяться с основным файлом манифеста при сборке проекта.

Читайте также:  Quik андроид соединение установить не удалось

Смотрите Проекты библиотек для Android для большей информации.

Развертывание

Для кросс-платформенного развертывания, ваш проект должен включать плагины для каждой поддерживаемой платформы (т.е. libPlugin.so для Android, Plugin.bundle для Mac и Plugin.dll для Windows). Unity автоматически выбирает правильный плагин для целевой платформы и включает его с плеером.

For specific Android platform (armv7, x86), the libraries (lib*.so) should be placed in the following:

Использование плагинов Java

Механизм Android-плагина также обеспечивает Java, который будет использоваться для взаимодействия с ОС Android.

Сборка Java-плагина для Android

Есть несколько способов создать плагин Java, но результатом во всех случаях является файл .jar, содержащий файлы .class для вашего плагина. Один из подходов — скачать JDK, затем скомпилировать файлы .java из командной строки с javac. Это создаст файлы .class, которые затем можно упаковать в .jar из командной строки с утилитой jar. Другой вариант заключается в использовании Eclipse IDE вместе с ADT.

Примечание: Unity ожидает Java-плагины, которые будут построены с использованием JDK v1.6. Если вы используете v1.7, вы должны включить “-source 1,6 -target 1,6” в параметрах командной строки для компилятора.

Использование ваших Java-плагинов из нативного кода

После того как вы создали свой ​​Java-плагин (.jar), вы должны скопировать его в папку Assets->Plugins->Android в проекте Unity. Unity упакует ваши файлы .class вместе с остальной частью Java-кода, а затем получить доступ к коду, используя Java Native Interface (JNI). JNI используется как при вызове нативного кода из Java, так и при взаимодействии с Java (или JavaVM) из нативного кода.

Чтобы найти Java код из нативной части, вы должны иметь доступ к Java VM. К счастью, доступ можно легко получить, добавив такую ​​функцию в свой C/C++ код:

Это все, что необходимо, чтобы начать использовать Java из C/C++. Полное объяснение JNI выходит за рамки этого документа. Однако его использование, как правило, включает в себя поиск определения класса, поиск метода конструктора ( ) и создание нового экземпляра объекта, как показано в этом примере:-

Использование Java-плагинов со вспомогательными классами

AndroidJNIHelper и AndroidJNI могут быть использованы для избавления от некоторых проблем с первичным JNI.

AndroidJavaObject и AndroidJavaClass автоматизируют множество задач и используют кэширование для ускорения вызовов к Java. Комбинация AndroidJavaObject и AndroidJavaClass надстраивается над AndroidJNI и AndroidJNIHelper , но также содержит много логики сама по себе (для управления автоматизацией). Эти классы также идут в ‘static’ версии для доступа к статическим членам Java классов.

Вы можете выбрать в зависимости от того, что вам подходит, будь то первичный JNI с помощью методов класса AndroidJNI , или AndroidJNIHelper вместе с AndroidJNI , и в конце концов AndroidJavaObject/AndroidJavaClass для максимальной автоматизации и удобства.

UnityEngine.AndroidJNI является оберткой для вызовов JNI доступных в C (как описано выше). Все методы этого класса являются статическими и соответствуют 1:1 Java Native Interface. UnityEngine.AndroidJNIHelper предоставляет вспомогательный модуль, используемый на следующем уровне, но предоставляется как открытые методы, потому что они могут быть полезны для некоторых частных случаев.

Экземпляры UnityEngine.AndroidJavaObject и UnityEngine.AndroidJavaClass соответствуют один-в-один экземпляру java.lang.Object и java.lang.Class (или их подклассов) на стороне Java, соответственно. Они по существу обеспечивают 3 типа взаимодействия с Java:-

  • Вызов метода
  • Получить значения поля
  • Установить значение поля
Читайте также:  Как настроить мышку для андроид

Call (Вызов) разделяется на две категории: Call (Вызов) ‘void’ метода, и Call (Вызов) метода, возвращающего не-void тип. Универсальный тип используется для представления типа возвращаемого методами, которые возвращают не-void тип. Get и Set всегда берут универсальный тип, представляющий тип поля.

Пример 1

Здесь мы создаем экземпляр java.lang.String, инициализируемстроку на свой выбор и извлекаем хеш значение для этой строки.

Конструктор AndroidJavaObject принимает минимум один параметр, имя класса, экземпляр которого хотим создать. Любые параметры после имени класса предназначены для вызова конструктора объекта, в данном случае строка “some_string”. Последующий Call (Вызов) метода hashCode() возвращает ‘int’, который мы используем в качестве параметра универсального типа в Call (Вызове) метода.

Примечание: Вы не можете создать экземпляр вложенного класса Java с помощью разделения точкой. Внутренние классы должны использовать разделитель $, и это должно работать в точечном и слэш формате. Так \[android.view.ViewGroup$LayoutParams или android/view/ViewGroup$LayoutParams могут быть использованы, где LayoutParams класс вложенный в класс ViewGroup\] .

Пример 2

Один из примеров плагина выше показывал, как получить директорию кэша для текущего приложения. Вот, как вы могли бы сделать то же самое на C# без плагинов:-

В этом случае, мы начинаем с AndroidJavaClass вместо AndroidJavaObject , потому что мы хотим получить доступ к статическому члену com.unity3d.player.UnityPlayer , а не создавать новый объект (экземпляр создается автоматически в Android UnityPlayer ). Затем мы получаем доступ к статическому полю “currentActivity”, но на этот раз мы используем AndroidJavaObject как универсальный параметр. Потому что фактический тип поля (android.app.Activity) — это подкласс java.lang.Object), и любой не-примитивный тип обязательно должен быть доступен как AndroidJavaObject . Исключением из этого правила являются строки, которые могут быть доступны непосредственно, даже если они не представляют собой примитивный тип в Java.

После чего это уже просто вопрос обхода Activity через getCacheDir() для получения объекта File, представляющего папку кэша с последующим вызовом getCanonicalPath() для получения строкового представления.

Конечно, в настоящее время вам не нужно делать этого, чтобы получить каталог кэша, поскольку Unity предоставляет доступ к директории кэша и файлов приложения с Application.temporaryCachePath и Application.persistentDataPath.

Пример 3

Наконец, здесь есть уловка для передачи данных из Java в код скрипта с помощью UnitySendMessage .

Класс Java com.unity3d.player.UnityPlayer теперь имеет статический метод UnitySendMessage , что эквивалентно функции UnitySendMessage в нативной части iOS. Он может быть использован в Java для передачи данных в код скрипта.

Здесь, однако, мы вызываем непосредственно из кода скрипта, который по сути передает сообщение Java. Это посылает обратный вызов нативному/Unity коду, чтобы доставить сообщение объекту с именем “Main Camera”. Этот объект имеет скрипт, который содержит метод, называемый “JavaMessage”.

Лучшая практика при использовании плагинов Java с Unity

Так как этот раздел в основном ориентирован на людей, которые не имеют большого опыта работы с JNI, Java и Android, мы предполагаем, что подход с AndroidJavaObject/AndroidJavaClass был использован для взаимодействия с кодом Java из Unity.

Первое, что нужно отметить, это то, что любая операция выполненная с AndroidJavaObject или AndroidJavaClass дорогая в отношении производительности (как первичный JNI подход). Крайне желательно, чтобы количество переходов между управляемым и нативным/Java кодом было минимальным, ради производительности, а также ясности кода.

У вас может быть метод Java, чтобы сделать всю фактическую работу, а затем использовать AndroidJavaObject/AndroidJavaClass для взаимодействия с этим методом и получения результата. Однако стоит иметь в виду, что вспомогательные классы JNI попробуют кэшировать столько данных, сколько возможно, чтобы улучшить производительность.

Читайте также:  Android read stream to string

Сборщик мусора Mono должен освободить все созданные экземпляры AndroidJavaObject и AndroidJavaClass после использования, но желательно держать их в операторе using()<> , чтобы они удалялись как можно скорее. Без этого вы не можете точно знать, когда они будут уничтожены. Если вы установите значение AndroidJNIHelper.debug в true, вы увидите запись деятельности сборщика мусора в журнале отладки.

Вы также можете непосредственно вызвать метод .Dispose() для гарантии, что нет сохранившихся Java-объектов. Фактически C# объект может жить немного дольше, но в конце концов будет удалён сборщиком мусора mono.

Расширение Java-кода UnityPlayerActivity

С Unity Android можно расширить стандартный класс UnityPlayerActivity (основной класс Java для Unity плеера на Android, аналогично AppController.mm на Unity iOS).

Приложение может переопределить любые и все основные взаимодействия между ОС Android и Unity Android. Вы можете cделать это, создав новую Activity, которая является производной от UnityPlayerActivity(UnityPlayerActivity.java можно найти в /Applications/Unity/Unity.app/Contents/PlaybackEngines/AndroidPlayer/src/com/unity3d/player на Mac и обычно в C:\Program Files\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\src\com\unity3d\player на Windows).

Чтобы сделать это, сначала найдите classes.jar , поставляемый с Unity Android. Он находится в папке установки (обычно C:\Program Files\Unity\Editor\Data (на Windows) или /Applications/Unity (на Mac)) в подпапке PlaybackEngines/AndroidPlayer/bin . Затем добавить PlaybackEngines/AndroidPlayer/bin в папку с классами, используемыми для компиляции новой Activity. Полученный(-ые) .class файл(ы) должны быть сжаты в .jar файл, а этот файл надо добавить в папку Assets->Plugins->Android . Поскольку манифест определяет запуск Activity, его также необходимо создать новый AndroidManifest.xml. Файл AndroidManifest.xml также должен быть помещен в папку Assets->Plugins->Android (размещение пользовательского манифеста полностью заменяет манифест Unity Android по умолчанию).

Новая Activity может выглядеть, как в следующем примере OverrideExample.java:

И соответствующий AndroidManifest.xml будет выглядеть так:

UnityPlayerNativeActivity

Кроме того, можно создать свой собственный подкласс UnityPlayerNativeActivity . Это будет иметь такой же эффект, как создать подкласс UnityPlayerActivity но с улучшенной задержкой ввода. Помните, однако, что NativeActivity был введен в Gingerbread и не работает со старыми устройствами. Поскольку события касания/движения обрабатываются в нативном коде, окна Java обычно не увидят эти события. Существует, однако, механизм переадресации в Unity, который позволяет, чтобы события распространялись на DalvikVM. Для доступа к этому механизму, необходимо изменить файл манифеста, выглядит следующим образом:-

Обратите внимание на атрибут “.OverrideExampleNative” в элементе Activity и два дополнительных элемента мета-данных. Первый элемент мета-данных является инструкцией по использованию библиотеки libunity.so для Unity. Второй обеспечивает события, которые будут переданы пользовательскому подклассу UnityPlayerNativeActivity.

Примеры

Пример нативного плагина

Простой пример использования кода нативного плагина можно найти здесь

В этом примере демонстрируется как код С может быть вызван из приложения Unity Android. Пакет содержит сцену, которая отображает сумму двух значений, рассчитанную нативным плагином. Пожалуйста, обратите внимание, что вам нужен будет Android NDKдля компиляции плагина.

Пример плагина Java

Используемый в примере код Java можно найти здесь

В этом примере демонстрируется как код Java может быть использован для взаимодействия с ОС Android, и как C++ создает мост между C# и Java. Сцена в пакете отображает кнопку, при нажатии на которую выдается каталог кэша приложения, как это определено в ОС Android. Пожалуйста, обратите внимание, что вам понадобится JDK и Android NDK для компиляции плагинов.

Здесь находиться подобный пример, но на основе предварительно собранной библиотеки JNI, чтобы обернуть нативный код в C#.

Источник

Оцените статью