web-dev-qa-db-ja.com

iOS向けUnity3dプラグインの構築方法

IOS用に構築された非常に小さなObjective-Cライブラリがあり、Unityにエクスポートしたい。すべての呼び出しをネイティブライブラリにマーシャリングするcsharpラッパーを記述する基本的なプロセスは理解していますが、どこから始めればよいのかまったくわかりません。他の開発者にも配布できるように、誰でも私のライブラリで統一パッケージを作成する方法をステップごとに説明していただけますか。

Unity3dのドキュメントは非常に短く、何も説明していません。

ありがとう。

61
highmaintenance

さて、MacでUnity3dで数日間プレイした後、私はついに理解しました。このガイドのコードはすべてダミーです。私は15分ほどでこのようなものを書いたので、間違いやタイプミスに悩まされることはありません。

1)Unityを開き、新しいプロジェクトを作成し(ファイル->新しいプロジェクト)、どこかに保存します

2)プロジェクトが生成されると、次の構造になります。

  • ProjectName/Assets(必要なもの)
  • ProjectName/Library(そこに何もありません)
  • ProjectName/ProjectSettings(あなたは気にしません)
  • ProjectName/ProjectName.sln(MonoDevelopプロジェクト)

3)ProjectName/Assetsに移動して、次のフォルダーを作成します:Plugins/iOS。最終的に、次のようなフォルダー構造になります。ProjectName/Assets/Plugins/iOS

4)コンパイル済みライブラリ(.a)ファイルと必要なヘッダーをProjectName/Assets/Plugins/iOS内に置くか、ライブラリのソースコード(.mm、.h、.mなど)をコピーします。通常、C#からのみC関数にアクセスできるため、何らかの方法でObjective-CのものをCコードでラップする必要があります。私の場合、Objective-Cオブジェクトはすべてシングルトンの形式で実装されているため、たとえば、Cスタイルのラッパーを作成するのは難しいです。

CWrapper.h

extern "C" void MySDKFooBarCFunction();

CWrapper.mm

#import "CWrapper.h"
#import "MyObjectiveCLibrary.h" // your actual iOS library header

void MySDKFooBarCFunction() {
    [MyObjectiveCLibrary doSomeStuff];
}

5)次に、ProjectName/Assetsに移動し、CSharpラッパークラス用のフォルダーを作成し、必要に応じて呼び出します。例:ProjectName/Assets/MySDK

6)MySDKフォルダー内にMySDK.csファイルを作成すると、C#ラッパーのダミーの例は次のようになります。

using UnityEngine;
using System;
using System.Runtime.InteropServices;

public class MySDK
{
    // import a single C-function from our plugin
    [DllImport ("__Internal")]
    private static extern void MySDKFooBarCFunction();

    // wrap imported C-function to C# method
    public static void FooBarCFunction() {
        // it won't work in Editor, so don't run it there
        if(Application.platform != RuntimePlatform.OSXEditor) {
            MySDKFooBarCFunction();
        }
    }
}

7)この内容を.unitypackageにパックするシェルスクリプトを作成し、プロジェクトフォルダーの隣に配置します(内部ではありません)。必要に応じて、スクリプト内のEXPORT_PATHおよびPROJECT_PATH変数を調整します。

#!/bin/sh

WORKDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
UNITY_BIN="/Applications/Unity/Unity.app/Contents/MacOS/Unity"
EXPORT_PATH="${WORKDIR}/ProjectName.unitypackage"
PROJECT_PATH="${WORKDIR}/ProjectName"
ASSETS_PATH="Assets"

$UNITY_BIN -batchmode -quit \
-logFile export.log \
-projectPath $PROJECT_PATH \
-exportPackage $ASSETS_PATH $EXPORT_PATH

8)作成されたbashスクリプトを実行して、パッケージのビルドを取得します。 Unity Editorの[ファイル]-> [ビルド設定]でアセットを生成すると、アセットのすべてのものがUnityプロジェクトのXCodeプロジェクトに含まれます。生成されたパッケージを使用してコードを他の開発者に配布すると、パッケージファイルをダブルクリックしてライブラリをUnityプロジェクトに簡単に含めることができます。

このスクリプトを実行するときにUnity Editorをシャットダウンすることを忘れないでください。そうしないと、パッケージのビルドに失敗する可能性があります。

問題があり、パッケージが表示されない場合、このスクリプトは常にログをexport.logに出力します

次の手順は、ライブラリのデモ統合プロジェクトを作成する場合にのみ意味があります(少なくともテストに適しています)

9)作成したUnityプロジェクト(ProjectName.unity)をAssets/MySDKDemoに配置して、パッケージ内にデモを作成できます。

10)Assets/MySDKDemo/MySDKDemo.csでデモUnity3dシーン用の簡単なスクリプトを作成します。例:

using UnityEngine;
using System;
using System.Collections;

public class MySDKDemo : MonoBehaviour
{   
    private GUIStyle labelStyle = new GUIStyle();
    private float centerX = Screen.width / 2;

    // Use this for initialization
    void Start ()
    {   
        labelStyle.fontSize = 24;
        labelStyle.normal.textColor = Color.black;
        labelStyle.alignment = TextAnchor.MiddleCenter;
    }

    void OnGUI ()
    {
        GUI.Label(new Rect(centerX - 200, 20, 400, 35), "MySDK Demo", labelStyle);
        if (GUI.Button(new Rect(centerX - 75, 80, 150, 35), "DoStuff"))
        {
            MySDK.FooBarCFunction();
        }
    }

}

11)Unity Editorに移動します。 Unityエディターの左側のサイドバーで「メインカメラ」を見つけて選択し、インスペクターパネルの下部(右側のサイドバー)でAddComponentをクリックし、スクリプト-> MySDKDemoスクリプトを選択します

12)XCodeプロジェクトをビルドし、デバイスで実行します。

いくつかのメモ

1)プラグインはUnityエディターでは機能しません。単にリアルタイムでコンパイルされていないためです.

2)この投稿では、マーシャリングや、ネイティブ<->マネージコード間のデータ/メモリ管理については詳しく説明されていないため、取り上げません。

Monoプロジェクトのネイティブライブラリとの相互運用

3)C#からCへのコールバックは、C#デリゲートを使用して渡すことができます。C側では標準関数宣言を使用し、C#側では同じ署名でデリゲートを宣言します。ブール値、整数、文字列(C:char *)は完璧に整列化されているようです(メモリ管理ポリシーと、メモリの解放または値のポリシーの返還責任者については説明しません)。

ただし、プラットフォームの制限により、すぐに使用できるiOSビルドでは動作しませんが、このトピックに関する便利なリンクであるMonoPInvokeCallbackAttributeを使用してC#-to-Cコールバックを実装できます。

実際、Unity 4にはAOT.MonoPInvokeCallbackAttributeが既に実装されており、アンマネージコードに渡すことができる静的なデリゲートに制限されていますが、何もないよりはましです。

4)UnityGetGLViewController関数を使用してUnity RootViewControllerを取得する方法があります。実装ファイルでこの関数を宣言するだけです。つまり:

extern UIViewController *UnityGetGLViewController();

RootViewControllerへのアクセスを取得する必要があるときはいつでもUnityGetGLViewController()を使用します。

5)詳細にはもっと多くの魔法とandいものがあります。Cインターフェイスをできるだけシンプルにしてください。そうしないと、マーシャリングが悪夢になり、マネージツーアンマネージドが一般的に高価になることにも留意してください。

6)ネイティブコードでいくつかのフレームワークを確実に使用し、リンカの問題は望ましくありません。たとえば、ライブラリでキーチェーンを使用する場合、Security.frameworkをXcodeプロジェクトに含める必要があります。

XUPorter を試してみることをお勧めします。Unityが追加の依存関係をXcodeプロジェクトに統合するのに役立ちます。

がんばろう!

83
highmaintenance

統一のためにiOSプラグインを作成する方法についての投稿を書きました。確認できます こちら 。それが役に立てば幸い。ありがとう。

5
Ashwani K