- 追加された行はこのように表示されます。
- 削除された行は
このように表示されます。
!!!ネイティブプラグインの呼び出し
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での編集時のみ呼ばれるプラグインとなります。
{{ref_image unity5_plugin_editor.png}}
プロジェクトウィンドウのプラグインのアイコンを選択します。
インスペクタウィンドウでエディタで使用する場合はSelect platforms for pluginsの「Editor」をOn、
Platform settingsのCPUでx86_64を選択すると64bit版DLL、x86を選択すると32bit版DLL。
OSはWindowsかOS Xか、など選択します。
{{ref_image unity5_plugin_editor_02.png}}
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フォルダに入れているか。
----
{{lastmodified}}