Copyright (C) DeNACo.,Ltd. All Rights Reserved.Copyright (C) DeNA Co.,Ltd. All Rights Reserved.
Unityネイティブプラグインマニアクス
DeNA Technology Conference 2017
1
Japanリージョンゲーム事業本部 開発基盤部
Haruto Otake
Sae Yamauchi
Copyright (C) DeNACo.,Ltd. All Rights Reserved.Copyright (C) DeNA Co.,Ltd. All Rights Reserved.
ネイティブプラグインのつくりかた
10
11.
Copyright (C) DeNACo.,Ltd. All Rights Reserved.
ネイティブプラグインとしての実装 (1)
ネイティブ実装と、それを呼び出すためのインターフェースを用意することで、
相互に呼び出しを行うことができる。
マネージドコード
⁃ ゲームコード(C#)に当たる
⁃ monoでビルドした場合は、仮想マシン上で実行されるコード
⁃ IL2CPPでビルドした場合は、最終的にはネイティブコードになる
ネイティブコード(アンマネージドコード)
⁃ C / C++ / Java 等で記述されたコード
11
マネージドコード (C#)
ネイティブコード
(C / C++ / Java等)
インターフェース
12.
Copyright (C) DeNACo.,Ltd. All Rights Reserved.
ネイティブプラグインとしての実装 (2) 実装例 (Androidの場合)
12
int add(int x, int y) { return x + y; } // test.c
int add(int x, int y); // test.h
libnative.so
// ゲームコード上での呼び出し(C#)
int result = add(1, 2);
// P/Invoke宣言(C#)
[DllImport("native")]
private static extern int add(int x, int y);
マネージドコード (C#)
ネイティブコード
インターフェース
13.
Copyright (C) DeNACo.,Ltd. All Rights Reserved.
必要な実装
A. 【ネイティブ】拡張機能のコア実装
B. 【ネイティブ】マネージドコードから呼び出すためのインターフェース
C. 【マネージド】ネイティブコードとの連携実装
D. 【マネージド】利用者向け呼び出しフロントエンド実装
13
マネージドコード (C#)
ネイティブコード
(例: OSSライブラリ)
インターフェース
C
D
A
B
14.
Copyright (C) DeNACo.,Ltd. All Rights Reserved.
必要な実装
A. 【ネイティブ】拡張機能のコア実装
B. 【ネイティブ】マネージドコードから呼び出すためのインターフェース
C. 【マネージド】ネイティブコードとの連携実装
D. 【マネージド】利用者向け呼び出しフロントエンド実装
14
マネージドコード (C#)
ネイティブコード
(例: OSSライブラリ)
インターフェース
C
D
A
B
15.
Copyright (C) DeNACo.,Ltd. All Rights Reserved.
拡張機能のコア実装 / マネージドコードから呼び出すためのインターフェース
ネイティブコード
⁃ 拡張機能のコア実装
⁃ ゲームエンジンを跨いで利用可能な技術資産にできる
インターフェース
⁃ マネージドコードから呼び出すためのインターフェース
⁃ C Linkageの関数として実装する
• 例 test.cpp
extern "C" int hoge();
int hoge() {
return 1;
}
15
マネージドコード (C#)
ネイティブコード
(例: OSSライブラリ)
インターフェース
C
D
A
B
16.
Copyright (C) DeNACo.,Ltd. All Rights Reserved.
必要な実装
A. 【ネイティブ】拡張機能のコア実装
B. 【ネイティブ】マネージドコードから呼び出すためのインターフェース
C. 【マネージド】ネイティブコードとの連携実装
D. 【マネージド】利用者向け呼び出しフロントエンド実装
16
マネージドコード (C#)
ネイティブコード
(例: OSSライブラリ)
インターフェース
C
D
A
B
Copyright (C) DeNACo.,Ltd. All Rights Reserved.
AndroidJavaObjectなど
AndroidのAPIやJARに含まれるコードを呼び出すことができるUnityのAPI
マネージドコードからクラス名を指定し呼び出すことができる。
参考: Unity マニュアル Android 用のプラグインをビルド
⁃ https://docs.unity3d.com/ja/current/Manual/PluginsForAndroid.html
using (AndroidJavaClass cls = new AndroidJavaClass("java.util.Locale")) {
using(AndroidJavaObject locale = cls.CallStatic<AndroidJavaObject>("getDefault")) {
Debug.Log("current lang = " + locale.Call<string>("getDisplayLanguage"));
}
}
上記ドキュメントに記載されている呼び出し例(C#):
19
20.
Copyright (C) DeNACo.,Ltd. All Rights Reserved.
UnitySendMessage
ネイティブコードからマネージドコードに文字列を渡すことができる。
指定したGameObjectの指定したメソッドに対して、stringを引数にして呼び出す。
ネイティブで一定処理を行った後に、結果を返したい場合などに使用する。
問題点
⁃ 非同期のため、同一フレーム間でメッセージを受け取れるわけではない
// GameObject名, メソッド名, 送信したい文字列
UnitySendMessage("GameObjectName", "MethodName", "Message to send");
20
21.
Copyright (C) DeNACo.,Ltd. All Rights Reserved.
必要な実装
A. 【ネイティブ】拡張機能のコア実装
B. 【ネイティブ】マネージドコードから呼び出すためのインターフェース
C. 【マネージド】ネイティブコードとの連携実装
D. 【マネージド】利用者向け呼び出しフロントエンド実装
21
マネージドコード (C#)
ネイティブコード
(例: OSSライブラリ)
インターフェース
C
D
A
B
22.
Copyright (C) DeNACo.,Ltd. All Rights Reserved.
利用者向けフロントエンド実装
C Linkage関数のインターフェースをC#で扱いやすくするために、ラッパーを実装
する。
実装例 マネージドコード(C#)
22
public static class HogeBindings {
[DllImport("hoge")]
public static extern IntPtr create(int x);
[DllImport("hoge")]
public static extern void remove(IntPtr context);
[DllImport("hoge")]
public static extern int exec(IntPtr context, int x);
}
public class Hoge : IDisposable {
private IntPtr context;
public Hoge(int x) {
context = HogeBindings.create(x);
}
public Dispose() { HogeBindings.remove(context); }
public int Exec(int x) {
return HogeBindings.exec(context, x);
}
}
23.
Copyright (C) DeNACo.,Ltd. All Rights Reserved.Copyright (C) DeNA Co.,Ltd. All Rights Reserved.
ネイティブプラグイン作成時の注意点と対応策
23