Как позвонить в GL.Выдайте событие Pluginevent в Unity3d и передайте параметры на сторону плагина в C

#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, передавая несколько параметров. Шаги следующие:

  1. получите указатель на функцию для функции C# (обратите внимание, что функция будет статической)
  2. передайте указатель этой функции в GL.Выпуск pluginevent
  3. внутри вашей статической функции 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();