Version: 5.4
デスクトップ向けのプラグインをビルド
アセットバンドル

低レベルネイティブプラグインインターフェース

基本的なスクリプトのインターフェースに加えて、プラグイン は Unity 上で発生したの特定のイベントをコールバックで受け取ることができます。これはたいてい、プラグインで低レベルのレンダリングを実装し、Unity のマルチスレッドレンダリングを操作可能にするために使用されます。

Unity が提供しているインターフェースを定義するヘッダはエディターと一緒に提供されています。

インターフェース レジストリ

プラグインは、主要な Unity イベントを扱うために UnityPluginLoadUnityPluginUnload をエクスポートします。正しい署名は IUnityInterface.h を参照してください。 IUnityInterfaces は、追加的な Unity API にアクセスするためにプラグインに提供されます。

# include "IUnityInterface.h"
# include "IUnityGraphics.h"
// Unity プラグインロードイベント
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
    UnityPluginLoad(IUnityInterfaces* unityInterfaces)
{
    IUnityGraphics* graphics = unityInterfaces->Get<IUnityGraphics>();
}

グラフィックドライバへのアクセス

プラグインは、 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 プラグインロードイベント
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
    UnityPluginLoad(IUnityInterfaces* unityInterfaces)
{
    s_UnityInterfaces = unityInterfaces;
    s_Graphics = unityInterfaces->Get<IUnityGraphics>();
        
    s_Graphics->RegisterDeviceEventCallback(OnGraphicsDeviceEvent);
        
    // OnGraphicsDeviceEvent(initialize) をプラグインのロードに手動で実行して
    // グラフィックスデバイスがすでに初期化されている場合でもイベントを逃さないようにします
    OnGraphicsDeviceEvent(kUnityGfxDeviceEventInitialize);
}
    
// Unity プラグインアンロードイベント
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: ユーザー初期化コード
            break;
        }
        case kUnityGfxDeviceEventShutdown:
        {
            s_RendererType = kUnityGfxRendererNull;
            //TODO: ユーザーシャットダウンコード
            break;
        }
        case kUnityGfxDeviceEventBeforeReset:
        {
            //TODO: ユーザー Direct3D 9 コード
            break;
        }
        case kUnityGfxDeviceEventAfterReset:
        {
            //TODO: ユーザー Direct3D 9 コード
            break;
        }
    };
}

レンダリングスレッド上のプラグインコールバック

Unity は当該プラットフォームでの CPU 数により実現できる範囲でレンダリングをマルチスレッド化することができます。マルチスレッドレンダリングを使うときレンダリング API コマンドは MonoBehaviour とは完全に別の、独立したスレッド上で実行します。そのため、いつでもプラグインからレンダリングを起動することが可能とは限りません。そして、レンダリングスレッドは干渉する可能性があります。

プラグインから どのような レンダリングを行う場合でも、プラグインはスクリプトから GL.IssuePluginEvent を参照しメインスレッドから呼び出されるようにする必要があります。例えば、カメラの OnPostRender 関数から GL.IssuePluginEvent を呼び出す場合、プラグインはカメラのレンダリング終了後すぐにコールバックを取得します。

UnityRenderingEvent コールバックのシグネチャは IUnityGraphics.h で示されます。
ネイティブプラグイン コードサンプル

// 特定のレンダリングイベントを処理するプラグイン関数
static void UNITY_INTERFACE_API OnRenderEvent(int eventID)
{
    //TODO: ユーザーレンダリングコード
}
    
// プラグイン特有のスクリプトにコールバックを渡すための自由に定義した関数
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();
    
// 指定のコールバックがレンダースレッドで呼び出されるようにキューで待機
GL.IssuePluginEvent(GetRenderEventFunc(), 1);

このコールバックは CommandBuffer.IssuePluginEvent によって CommandBuffers に追加することもできます。

低レベルレンダリングプラグインの例は bitbucket にあります。2 例を紹介しています。 ここでダウンロードできます。 (NativeRenderingPlugin フォルダー)

  • すべての正規レンダリングが完了した後に、C++コードから回転する三角形を描画します。
  • Texture.GetNativeTexturePtr を利用してアクセスし、C++ のコードでプロシージャルなテクスチャを塗りつぶします。

プロジェクトは以下の仕様で動作します。

  • 以下を伴う Windows (Visual Studio 2015): Direct3D 9, Direct3D 11, Direct3D 12, OpenGL
  • 以下を伴う Mac OS X (Xcode): Metal, OpenGL
  • 以下を伴う Windows Store Apps (Windows 10、Windows 8.1): Direct3D 11, Direct3D 12
デスクトップ向けのプラグインをビルド
アセットバンドル