トップ 一覧 検索 ヘルプ RSS ログイン

unity_native_plugin_firstの変更点

  • 追加された行はこのように表示されます。
  • 削除された行はこのように表示されます。
!!!ネイティブプラグインの呼び出し

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}}