Version: 2022.3
言語: 日本語
物理演算のパフォーマンス最適化
Unity をネイティブ iOS アプリケーションに統合

iOS 用のプラグインをビルド

このページでは、iOS プラットフォーム向けの ネイティブ コードプラグイン のビルド方法について説明します。

iOS 用のネイティブプラグインを使用したアプリケーションのビルド

iOS のネイティブプラグインでアプリケーションをビルドするには、以下を行います。

  1. 呼び出したい各ネイティブ関数に対し、以下のように C# ファイルで extern メソッドを定義します。

    [DllImport ("__Internal")] 
    
    private static extern float FooPluginFunction();
    
  2. ネイティブコードのソースファイルを Unity プロジェクトに加えます。

  3. Plugin Inspector ウィンドウでプラグインの設定をカスタマイズします。例えば、ネイティブコードが iOS 特有の場合は、プラグインが iOS に対してのみ有効であることを確認します。

ノート: C++ (.cpp) または Objective-C++ (.mm) を使用してプラグインを実装する場合は、名前マングリングの問題を回避するために、C リンケージを使用して関数を宣言する必要があります。

extern "C" {
  float FooPluginFunction();
}

C または Objective-C で書かれたプラグインは、名前マングリングを使用しないため、これを使用する必要がありません。

C# のプラグインを使用

iOS ネイティブプラグインは、実際のデバイスにデプロイされている場合にのみ呼び出すことができるため、すべてのネイティブコードメソッドを追加の C# コードレイヤーでラップする必要があります。このコードは、UNITY_IOS && !UNITY_EDITOR 条件付きコンパイルを使用するか、Application.platform を確認し、アプリケーションがデバイスで実行されているときにのみネイティブメソッドを呼び出す必要があります。これを実装する簡単な方法は以下のとおりです。

void MyMethod()
{
# if UNITY_IOS && !UNITY_EDITOR
    CallNativeMethodImplementation();
# else
    CallEditorMethodImplementation();
# endif
}

実装の詳細を確認するには、以下の Bonjour Browser サンプルをダウンロードしてください。

ネイティブコードから C# を呼び出す

Unity iOS は、ネイティブからマネージへの限定的なコールバック機能をサポートします。これは、以下の 2 つの方法のいずれかで行うことができます。

  • UnitySendMessage 使用
  • デリゲート経由

UnitySendMessage を使用

このオプションは簡単ですが、いくつかの制限があります。以下のようになります。

UnitySendMessage("GameObjectName1", "MethodName1", "Message to send");

3 つのパラメーターがあります。

  • ターゲット GameObject の名前
  • そのオブジェクト上で呼び出すスクリプトメソッド
  • 呼び出されたメソッドに渡すためのメッセージ文字列

UnitySendMessage 使用には以下の制限があります。

  1. ネイティブコードからは、以下のシグネチャに呼応するスクリプトメソッドのみを呼び出すことができます。void MethodName(string message);
  2. UnitySendMessage への呼び出しは非同期であり、1 フレーム遅延します。
  3. 2 つ以上のゲームオブジェクトが同じ名前の場合は、UnitySendMessage を使用すると競合が発生する可能性があります。

デリゲートを使用

これはより複雑なオプションです。デリゲートを使用する場合、C# 側のメソッドは静的で、MonoPInvokeCallback 属性でマークされています。メソッドをデリゲートとして extern メソッドに 渡す必要があります。extern メソッドは、関数としてネイティブコードに実装され、対応するシグネチャを持つ関数へのポインターを取ります。次に、ネイティブコードの関数ポインターが C# 静的方法に戻ります。

このメソッドの C# コードは以下のようになります。

delegate void MyFuncType();

[AOT.MonoPInvokeCallback(typeof(MyFuncType))]

static void MyFunction() { }

static extern void RegisterCallback(MyFuncType func);

コールバックを受け取る C コードは以下のようになります。

typedef void (*MyFuncType)();

void RegisterCallback(MyFuncType func) {}

自動的なプラグインインテグレーション

Unity は自動化されたプラグインインテグレーションをサポートします。Plugin Inspector ウィンドウで以下の拡張子を持つファイルを iOS 用に有効にできる場合は、それらすべてを生成した Xcode プロジェクトにコピーします。拡張子は、.a.m.mm.c.cpp.h です。これらの拡張子を持つファイルが Assets/Plugins/iOS フォルダーに配置されている場合、Unity は iOS プラットフォームに対してのみそれらを有効にします。

ノート: ファイルが生成された Xcode プロジェクトにコピーされた後、それらは Unity プロジェクトの対応するファイルにリンクされなくなります。Xcode でこれらのファイルを変更した場合は、逆に Unity プロジェクトにコピーする必要があります。そうでないと、Unity は次にプロジェクトをビルドするときにそれらを上書きします。

この Inspector ウィンドウは、プラグインが iOS で有効になっていることを示しています
この Inspector ウィンドウは、プラグインが iOS で有効になっていることを示しています

iOS のヒント

  1. マネージコードからアンマネージコードの呼び出しは、iOS 上でプロセッサに高負荷を与えます。フレームごとに複数のネイティブメソッドを呼び出さないでください。

  2. ネイティブメソッドを追加の C# レイヤーでラップします。このレイヤーはデバイス上でネイティブコードを呼び出し、エディターでダミーの値を返します。

  3. ネイティブメソッドから返される文字列値は UTF–8 でエンコードされ、ヒープに割り当てられます。Mono マーシャリングは、このような文字列に対しては制限がありません。

Bonjour Browser のサンプル

ネイティブコードのプラグインを使用した簡単な例は Bonjour Browser Sample からダウンロードできます。

この例では、Unity iOS アプリケーションから Objective-C コードを呼び出す方法を紹介します。このアプリケーションはシンプルな Bonjour クライアントを実装し、以下の対象で構成されています。

  • Unity iOS プロジェクト - Plugins\Bonjour.cs はネイティブコードへの C# インターフェースであり、BonjourTest.cs はアプリケーションロジックを実装するスクリプトです。
  • ネイティブコード (Assets/Plugins/iOS に保存) - Automated plug-in Integration セクションで説明されているように、ビルドされた Xcode プロジェクトに追加する必要があります。
物理演算のパフォーマンス最適化
Unity をネイティブ iOS アプリケーションに統合