Unity製アプリからCore MLモデルを利用する
"unity plugin ios core ml"でググると、上位3つに以下が出てくる
"unity core ml"でこういうのも見つけた。
1つ目のリンクのフォーラム内では2つ目のリンクの`UnityVision-iOS`のURLが提示されており、事実上OSSとしてはこれが一番参照されてそう。
この`UnityVision-iOS`のARKitExample2をビルドしてみると、次のようなリアルタイム物体認識サンプルが動いた。(gifは同リポジトリのREADMEから拝借)
無事動作が確認できたところで、どのように実装されているか、ソースを読んでみる。
Unity iOS Native Plugin
さて、ソース読むぞとUnityプロジェクトを開いてみたものの、そういえばUnityプロジェクトの読み方がよくわからない。触ったことはあるのでオブジェクトとC#コードの関係ぐらいはわかるが、「プラグイン」にはC#のコードとSwiftのコードがあって、それらがどのように連携しているかがよくわからない。
ので、まずはUnityのネイティブプラグインってどうやってつくるんだっけ?(≒どういう仕組みで動いてるんだっけ?)というのをおさらいする。
調べると、日本語ではこの記事が一番正確でわかりやすそうだった。
ポイントとしては、Objective-C, Objective-C++のコードをCでラップしておくと、
#ifdef __cplusplus
extern "C" {
#endif
// C#から呼ばれる関数
void sampleMethod1() {
NSLog(@"sampleMethod1 called.");
}
#ifdef __cplusplus
}
#endif
次のようにC#側では定義したCの関数と同じ名前でextern staticメソッドを定義でき、
using System.Runtime.InteropServices;
public class Sample {
// Sample.mm で定義しているCの関数を、以下のようにC#側で定義する
[DllImport("__Internal")]
private static extern void sampleMethod1();
}
このC#のstaticメソッドを呼ぶと、定義したCの関数が呼ばれる(つまりラップしているObjCコードが実行される)、ということらしい。
SwiftコードはObjC/ObjC++でブリッジする。
つまりこういう関係:
C# → C → ObjC(++) → Swift
上の記事によると、
Objective-Cのソースファイルは、Assets/Plugins/iOSに置く
とあるが、これは必須なのかはわからない。UnityVision-iOSのUnityプロジェクトでは Assets/Scripts/Possible/Vision/Plugins/iOS に置かれていた。どこかで「ネイティブコードへのパス」みたいなビルド設定項目があり、Unity側でのビルド時にシンボル有無のチェックをやりつつここにあるソースコードは生成するXcodeプロジェクトにそのまま含める、みたいなことだろうか。
Unity-ARKit-PluginとAR Foundation
UnityVision-iOSではこの公式プラグインを使ってARKitの機能を使っているようだが(Assets/UnityARKitPlugin)、これはもうdeprecatedで、AR Foundationを使えとなっている。
AR FoundationはARKit 3が出るタイミングでリリースされたようだ。で、結局のところARKitをたたくところはプラグインを使うらしい(しかしUnity-ARKit-Pluginではない)。
AR Foundation自体は、Unity開発者が使用できるインターフェイスを提供するだけで、AR機能自体は実装していないため、iOSならARKit XR Plugin、AndroidならARCore XR Pluginが必要
UnityとCore MLモデルの連携
さて、だいたい「つくり」を理解できたところで、そもそも興味あったこの部分のコードをみていく。
最後まで読んでいただきありがとうございます!もし参考になる部分があれば、スキを押していただけると励みになります。 Twitterもフォローしていただけたら嬉しいです。 https://twitter.com/shu223/