勉強不足で至らんブログ

勉強不足ですが、何か発信できればと思っています。

Unityのネイティブプラグイン(macOS/iOS/tvOS)のソースコードを共通化する

ネイティブプラグインの動作確認

iOS/tvOSのネイティブプラグインはEditorでは動かせません。そこでmacOSで同じソースコードを動かせばいいのでは?と考えて動かしてみました。

ただ全てが動くわけではないと思いますし一部機能の制限が入ります。調べ尽くしてないので、もしかすると使えます。わかっているのは以下の一点です。

  • entitlementファイルを使う場合は.bundleにcodesignができれば動きそう(パッと試した感じはできなかった)

一点といいつつ結構範囲が大きいです。あくまでEditorで動かす.bundleにする際にできないというだけで.appにcodesignを使えば動くはずです。

リポジトリはこちら

github.com

Editor(macOS)での動作はもちろん、シミュレーターになりますがiOS/tvOSで動作確認をしました。

Editor(macOS) iOS tvOS
f:id:MakeTake:20200202160024p:plain f:id:MakeTake:20200202160042p:plain f:id:MakeTake:20200202160047p:plain

実装

今回Swiftにてコアのコードを記述しました。

import Foundation

@objcMembers
public class Sample : NSObject {
    
    public override init() {
        super.init()
    }
    
    public func Call() -> String {
        "From Swift Code"
    }
}

Objective-CでラップしてC#側でStringをTextMeshProForUGIに表示させています。

Editorで動かすためのXcodeProjectを作る

UnityのPluginsディレクトリに.swiftや.mmがある前提で話をします。

まずはXcodeでProjectの新規作成を行ます。 f:id:MakeTake:20200202160853p:plain

UnityEditorでは.bundleというフォーマットで動作をするのでBundleのテンプレートを選択します。

次にプロジェクト名を求められるのでお好きなプロジェクト名を入力します。

これで保存場所を選択して作成完了です。

これからUnityのPlugins配下にあるファイルを参照してXcodeのプロジェクトに含めます。 ファイルを選ぶ際にコピーするかどうかのオプションがりますが別ファイルになってしまうのでOFFにしておいた方が良いです。

info.plistの入っているディレクトリを右クリックして以下の項目を選択します。 f:id:MakeTake:20200202172214p:plain

次にSwiftを使用する設定です。 先ほどのファイル追加で処理が走り、Swiftなどの設定が増えます。そこで f:id:MakeTake:20200202172228p:plain

左の青いアイコンを選択して Build Settings を選びます。そこから Basic Customized All と選ぶポイントがあるので All にして検索ボックスに -swift.h と検索します。

そして Objective-C Generated Interface Header Name のところをUnityのPlayerSettingsで設定するProduct Nameを確認して {ProductName}-Swift.h と入力しておきます。

こうすることでUnityでiOS/tvOSのプロジェクトが吐かれた時にエラーが出なくなります。

これで準備ができたのでXcodeのRunボタンでDebugモードでビルドします。 f:id:MakeTake:20200202162612p:plain

ビルドすると Products ディレクトリ配下にbundleができるのでUnityのPluginsディレクトリ配下におきます。

f:id:MakeTake:20200202172243p:plain

Show in Finder を選択するとFinderでドラッグ&ドロップできるのでおすすめです。(xcodeのpostprocessに移動するscriptを書けばいいのですがめんどくさかった…)

Editorで動かす準備ができました。

C#プラグインを呼ぶ

C#で呼ぶ処理を書いて動かしてみましょう。

今回はC#でこう書きました。

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

namespace ApplePlatformNativePlugin {

    public class SampleText : MonoBehaviour
    {

        [SerializeField] private TextMeshProUGUI centerText;
        
#if UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX
        private const string LibraryName = "XcodeProject";
#elif (UNITY_IOS || UNITY_TVOS) && !UNITY_EDITOR
        private const string LibraryName = "__Internal";
#endif
        
        
        [DllImport (LibraryName)]
        private static extern string CallNativeString();
        
        void Start()
        {
            centerText.text = CallNativeString();
        }
    }
    
}

これでSceneに配置してUIに表示させています。

おわりに

以上がAppleのプラットフォームのネイティブプラグインを共通化させEditorで確認する方法でした。これであれば実機でしか動かせない!という時も処理だけならEditorで簡易に確認が可能かと思います。 資格情報の署名がわからず、このままでは機能が一部動作しませんが一旦はいいかなと思っています。