ネイティブプラグインの呼び出し
C/C++などで書かれた外部機能を呼び出します。
- ネイティブ実行であるので、速度が確保できる
- 他ツールとの連携
などの利点があります。
手順としては以下のようになります。
- Win/Macの動的ライブラリ(dll)の形式で機能を作成
- Unityのプロジェクトにdllを配置
- 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秒