#unity3d #opengl-es #android-unity-plugin
Вопрос:
Я пытаюсь написать плагин для Unity, который передает информацию между родной стороной Android (но то же самое может относиться к любой другой библиотеке dll или около того) и стороной unity. Информация, которой я хочу поделиться, связана с OpenGL. В документах Unity указано, что все, что должно выполняться в потоке визуализации, должно вызываться через GL.IssuePlugInEvent
функцию. Эта функция, однако, довольно строга по параметрам: ей нужно вызвать функцию с определенной сигнатурой:
Обратный вызов должен быть собственной функцией подписи «void UNITY_INTERFACE_API UnityRenderingEvent(int EventID)».
и имеет только дополнительный параметр EventID.
Как я могу затем передать обратно информацию на стороне unity из библиотеки so?
Ответ №1:
Примеры Unity для создания плагина и использования IssuePluginEvent охватывают случай, когда вы хотите/должны напрямую вызывать функцию C, и эта функция принимает в качестве параметра только идентификатор события. Если читатель имеет опыт работы на CC и не знаком с C#, это может ввести в заблуждение. На самом деле, вы действительно можете вызвать функцию C# с помощью этого простого трюка, и внутри этой функции вызывайте свои функции C, передавая несколько параметров. Шаги следующие:
- получите указатель на функцию для функции C# (обратите внимание, что функция будет статической)
- передайте указатель этой функции в GL.Выпуск pluginevent
- внутри вашей статической функции C#, в зависимости от случая EventID, вызовите соответствующую функцию C
void Update()
{
GL.IssuePluginEvent(RenderThreadHandlePtr, GL_INIT_EVENT); // example
}
/// <summary> Renders the event delegate described by eventID. </summary>
/// <param name="eventID"> Identifier for the event.</param>
private delegate void RenderEventDelegate(int eventID);
/// <summary> Handle of the render thread. </summary>
private static RenderEventDelegate RenderThreadHandle = new RenderEventDelegate(RunOnRenderThread);
/// <summary> The render thread handle pointer. </summary>
public static IntPtr RenderThreadHandlePtr = Marshal.GetFunctionPointerForDelegate(RenderThreadHandle);
public const int GL_INIT_EVENT = 0x0001;
public const int GL_DRAW_EVENT = 0x0002;
/// <summary> Executes the 'on render thread' operation. </summary>
/// <param name="eventID"> Identifier for the event.</param>
[MonoPInvokeCallback(typeof(RenderEventDelegate))]
private static void RunOnRenderThread(int eventID)
{
switch (eventID)
{
case GL_INIT_EVENT:
glInit(par1, par2, par3); // C function with 3 parameters
break;
case GL_DRAW_EVENT:
glStep();
GL.InvalidateState();
break;
}
}
[DllImport("hello-jni")]
private static extern void glInit(int par1, int par2, int par3);
[DllImport("hello-jni")]
private static extern void glStep();