Version: 5.3
데스크톱 플랫폼용 플러그인 빌드
AssetBundles

Low-level Native Plugin Interface

기본적인 스크립트 인터페이스 외에 Unity의 네이티브 코드 플러그인은 특정 이벤트가 발생했을 때 콜백을 받을 수 있습니다. 주로 플러그인에서 로우 레벨 렌더링을 구현하는 데 활용되며 Unity의 멀티스레드 렌더링과 구동되게 합니다.

Unity 에디터에서 노출되는 인터페이스를 정의하는 헤더는 에디터와 함께 제공됩니다.

Interface Registry

A plugin should export UnityPluginLoad and UnityPluginUnload to handle main Unity events. See IUnityInterface.h for the correct signatures. IUnityInterfaces is provided to the plugin to access further Unity APIs.

    #include "IUnityInterface.h"
    #include "IUnityGraphics.h"
    // Unity plugin load event
    extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
        UnityPluginLoad(IUnityInterfaces* unityInterfaces)
    {
        IUnityGraphics* graphics = unityInterfaces->Get<IUnityGraphics>();
    }

Access to the Graphics Device

플러그인은 IUnityGraphics 인터페이스로 일반 그래픽 디바이스 기능에 액세스할 수 있습니다. Unity 초기 버전에서는 그래픽 디바이스의 이벤트에 대한 알림을 받기 위해 UnitySetGraphicsDevice 함수를 익스포트해야 했지만, Unity 5.2부터 새로운 IUnityGraphics 인터페이스(IUnityGraphics.h에 있음)는 콜백을 등록할 방법을 제공합니다.

    #include "IUnityInterface.h"
    #include "IUnityGraphics.h"
    
    static IUnityInterfaces* s_UnityInterfaces = NULL;
    static IUnityGraphics* s_Graphics = NULL;
    static UnityGfxRenderer s_RendererType = kUnityGfxRendererNull;
    
    // Unity plugin load event
    extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
        UnityPluginLoad(IUnityInterfaces* unityInterfaces)
    {
        s_UnityInterfaces = unityInterfaces;
        s_Graphics = unityInterfaces->Get<IUnityGraphics>();
        
        s_Graphics->RegisterDeviceEventCallback(OnGraphicsDeviceEvent);
        
        // Run OnGraphicsDeviceEvent(initialize) manually on plugin load
        // to not miss the event in case the graphics device is already initialized
        OnGraphicsDeviceEvent(kUnityGfxDeviceEventInitialize);
    }
    
    // Unity plugin unload event
    extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
        UnityPluginUnload()
    {
        s_Graphics->UnregisterDeviceEventCallback(OnGraphicsDeviceEvent);
    }
    
    static void UNITY_INTERFACE_API
        OnGraphicsDeviceEvent(UnityGfxDeviceEventType eventType)
    {
        switch (eventType)
        {
            case kUnityGfxDeviceEventInitialize:
            {
                s_RendererType = s_Graphics->GetRenderer();
                //TODO: user initialization code
                break;
            }
            case kUnityGfxDeviceEventShutdown:
            {
                s_RendererType = kUnityGfxRendererNull;
                //TODO: user shutdown code
                break;
            }
            case kUnityGfxDeviceEventBeforeReset:
            {
                //TODO: user Direct3D 9 code
                break;
            }
            case kUnityGfxDeviceEventAfterReset:
            {
                //TODO: user Direct3D 9 code
                break;
            }
        };
    }

Plugin Callbacks on the Rendering Thread

Rendering in Unity can be multithreaded if the platform and number of available CPUs will allow for it. When multithreaded rendering is used, the rendering API commands happen on a thread which is completely separate from the one that runs MonoBehaviour scripts. Consequently, it is not always possible for your plugin to start doing some rendering immediately, since might interfere with whatever the render thread is doing at the time.

플러그인에서 모든 렌더링을 하려면 플러그인 스크립트에서 GL.IssuePluginEvent를 호출해야 합니다. 그러면 제공된 네이티브 함수를 렌더 스레드에서 호출합니다. 예를 들어 카메라의 OnPostRender 함수에서 GL.IssuePluginEvent를 호출하면 카메라가 렌더링을 종료한 직후 플러그인이 콜백됩니다.

UnityRenderingEvent 콜백의 시그니처는 IUnityGraphics.h에서 제공합니다. 네이티브 플러그인 코드 예제:

    // Plugin function to handle a specific rendering event
    static void UNITY_INTERFACE_API OnRenderEvent(int eventID)
    {
        //TODO: user rendering code
    }
    
    // Freely defined function to pass a callback to plugin-specific scripts
    extern "C" UnityRenderingEvent UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
        GetRenderEventFunc()
    {
        return OnRenderEvent;
    }

관리되는 플러그인 코드 예제:

    #if UNITY_IPHONE && !UNITY_EDITOR
    [DllImport ("__Internal")]
    #else
    [DllImport("RenderingPlugin")]
    #endif
    private static extern IntPtr GetRenderEventFunc();
    
    // Queue a specific callback to be called on the render thread
    GL.IssuePluginEvent(GetRenderEventFunc(), 1);

이런 콜백은 현재 CommandBuffer.IssuePluginEvent를 통해 CommandBuffers에 추가됩니다.

예제

An example of a low-level rendering plugin can be downloaded here. It demonstrates two things:

  • 모든 정규 렌더링이 완료된 후 C++ 코드에서 회전하는 삼각형을 렌더링합니다.
  • Texture.GetNativeTexturePtr로 C++ 코드에 접근해 절차적 텍스처를 채웁니다.

프로젝트는 다음에서 작동합니다.

  • Windows (Visual Studio 2013) and Mac OS X (Xcode 3.2) and uses Direct3D 9, Direct3D 11, Direct3D 12 or OpenGL depending on the platform. Direct3D 9 code part also demonstrates how to handle “lost” devices.
  • Windows Store Apps (see RenderingPlugin\WSAVisualStudio2013 for more information)
데스크톱 플랫폼용 플러그인 빌드
AssetBundles