トップ 差分 一覧 ソース 検索 ヘルプ RSS ログイン

unity_native_plugin_first

ネイティブプラグインの呼び出し


C/C++などで書かれた外部機能を呼び出します。

  • ネイティブ実行であるので、速度が確保できる
  • 他ツールとの連携

などの利点があります。

手順としては以下のようになります。

  1. Win/Macの動的ライブラリ(dll)の形式で機能を作成
  2. Unityのプロジェクトにdllを配置
  3. Unityのスクリプトで外部関数を定義して関数呼び出し

  DLLの作成 (Windows)


Visual Studio 2013でDLLを作成するとします。

  • プロジェクトの構成プロパティで「全般」-「構成の種類」で「ダイナミックリンクライブラリ」を選択
  • プロジェクトの構成プロパティで「C/C++」-「プリコンパイル済みヘッダー」の「プリコンパイル済みヘッダーを使用しない」を選択

として、DLLをビルドできるようにプロジェクトを変更しておきます。

main.cppとして以下のように記述。

#include <windows.h>
#include <stdio.h>

#define DLL_API extern "C" __declspec(dllexport) 

BOOL WINAPI DllMain(HANDLE hModule, DWORD fdwReason, LPVOID lpReserved) {
   switch (fdwReason) {
       case DLL_PROCESS_ATTACH:
           break;

       case DLL_THREAD_ATTACH:
           break;

       case DLL_THREAD_DETACH:
           break;

       case DLL_PROCESS_DETACH:
           break;
   }

   return TRUE;
}

DLL_API int ext_add(int a, int b) {
   return a + b;
}

DLL_API int ext_sub(int a, int b) {
   return a - b;
}

ビルドすると、DLLができます。外部関数として「ext_add」「ext_sub」の2つの関数が用意された状態になります。
「TestDLL.dll」というファイル名としました。

  Unity上のプロジェクトにDLLをコピーして割り当て


参考 : https://docs.unity3d.com/ja/current/Manual/Plugins.html

Plugins
  x86
    TestDLL.dll    ... 32bit版のDLL
  x86_64
    TestDLL.dll    ... 64bit版のDLL

のようにプラグインをプロジェクトに配置。
Editor内に入れると、Unity Editorでの編集時のみ呼ばれるプラグインとなります。


プロジェクトウィンドウのプラグインのアイコンを選択します。
インスペクタウィンドウでエディタで使用する場合はSelect platforms for pluginsの「Editor」をOn、
Platform settingsのCPUでx86_64を選択すると64bit版DLL、x86を選択すると32bit版DLL。
OSはWindowsかOS Xか、など選択します。

Applyボタンを押して確定します。これを各プラグインのDLLごとに設定。

※ Editor/実行時どちらも動作し、特にEditorに依存しない場合は「Editor」はOffでいい ?
Editor使用時に、「Editor」をOnにするとDllの関数割り当てに失敗する場合がありました。


  スクリプトから呼び出し


以下が必要。

using UnityEngine;
using UnityEditor;                     // Unity Editor使用時.
using System.Runtime.InteropServices;  // DLL読み込みに必要.

クラスの先頭で、

[DllImport("DLL名")] private static extern int ext_add(int a, int b);

のように関数ごとに書式を記述するとマッピングできる。
あとは普通に関数として呼ぶだけ。

public class EditorTest : EditorWindow {
   // DLL関数をマッピング.
   [DllImport("TestDLL")] private static extern int ext_add(int a, int b);
   [DllImport("TestDLL")] private static extern int ext_sub(int a, int b);

   void foo () {
     int cVal = ext_add(20, 12);    // 外部関数として呼ぶ
   }
}

  配列を渡す


DLLのC/C++側で「void foo (int *v);」のように実装し、結果を配列に格納する場合、または配列をC/C++側に渡す場合。

Unity側のC#では、

[DllImport("TestDLL")] private static extern void foo(int[] v);

と記述。

int [] vData = new int[5];
foo(vData);

のようにアクセスできる。

この場合は参照渡しなので、読み込み/書き込みどちらでも行える。

  Vector2/Vector3の配列を渡す


DLLのC/C++側で「void foo(float* v2Array, float* v3Array);」のように実装し、
第一引数は配列要素の(v2Array[0], v2Array[1]), (v2Array[2], v2Array[3]),,,でVector2の要素、
第二引数は配列要素の(v2Array[0], v2Array[1], v2Array[2]), (v2Array[3], v2Array[4], v2Array[5]),,,でVector3の要素、とする。

Unity側のC#では、

[DllImport("TestDLL")] private static extern void foo(Vector2[] v2, Vector3[] v3);

と記述。
この場合は参照渡しなので、読み込み/書き込みどちらでも行える。

  DLLが読み込まれていない場合のチェック項目


dllが読み込まれていないというエラーが出るときの確認事項です。

  • プラグインの設定をEditorで変更した場合、一度Unity Editorを再起動
  • dll側で外部関数が「extern "C" __declspec(dllexport)」で指定されているかチェック
  • dll側で他のdllを参照する場合、それもUnityのPluginsフォルダに入れているか。


最終更新時間:2019年01月04日 13時09分50秒