Xamarin.Android で Unity as a Library (をやろうとしてうまくいかなった話)
はじめに
この記事は Unity ・・・ではなく Xamarin Advent Calendar 2020 の 6 日目の記事です。
表題の通り、 Xamarin.Android で Unity as a Library をやろうとしたのですが、うまくいく目途が立たなかったので経過報告的な記事でお茶を濁してしまおうかと・・・ すいません。
追記 (12/8):
この記事の内容を試していただいてうまくいったとのことです!
ありがとうございました。
Unity as a Library とは
- Unity as a Library を使用する
- ネイティブモバイルアプリケーションに Unity で作成した機能を追加できる「Unity as a Library」のご紹介
- Unity as a LibraryによるUIネイティブ化
"Unity as a Library" は他のアプリから Unity で実装したコードを「ライブラリ」として実行できるようにする仕組みです。
当初は Andorid/iOS のみのサポートでしたが、後に Windows でも対応しています。 Windows については以前記事を書きました。
今回の環境は次の通りです。
- Windows 10
- Unity 2019.4.15f1
- Android Studio 4.1.1
- Visual Studio 2019 16.8.1
Unity as a Library を試す
とりあえず試すには公式のサンプルがよいです。手順は こちら (Android 版) に書かれています。
この手順には書かかれていませんが、 Unity 上で "Project Settings - Player - Configuration" で "Scripting Backend" を "IL2CPP" に設定しないと最終的なバイナリは動作しませんでした (合わせて Target Architectures の ARM64 もチェック) 。
Build Settings で "Export Project" にチェックを入れることで Android Project が出力されます。後段の Android Studio での作業で、 Unity での出力先を "UnityProject\androidBuild" にしている事を前提として組まれているのでそこも注意です (私は読み飛ばしていて最初ひっかかりました) 。
Xamarin.Android に移植する
今回は上記の公式サンプルを Xamarin.Android 化してみます。
同じことをやられている先人様です。
Unity のライブラリを AAR 化する
Xamarin.Android で Android の Java コードをインポートするには jar か aar にしたものを利用しますが、今回はネイティブコードを含んでいるので aar にする必要があります。
- コンソールを開く
- 前項で Unity でビルドした Android プロジェクト (UnityProject\androidBuild) に移動
- "gradlew assembleRelease" を実行
で "unityLibrary\build\outputs\aar\unityLibrary-release.aar" に出力されます。
Visual Studio でプロジェクトと AAR Binding Library の作成をする
- VS2019 を起動し、 "Android アプリ (Xamarin)" - "単一ビューアプリ" でプロジェクトを作成します。
- ソリューション右クリック → "追加 - 新しいプロジェクト" で "Android バインドライブラリ" を追加します。
- バインドライブラリの Jars フォルダに先ほど出力した unityLibrary-release.aar を D&D して追加します。
- unityLibrary-release.aar を選択し、プロパティの "ビルドアクション" で "LibraryProjectZip" を選択します。
- アプリ側の参照にバインドライブラリを追加します。
これで UaaL のコードを Xamarin.Android のアプリ側からアクセスできるようになります。
コードを書く
今回は移植なので 元の Java コード を C# に移植します。 Gist に参考実装を上げました (Unity Companion License) 。
content_main.xml も同様に移植する必要がありますが、起動画面の UI は本質ではないので適当でもよいと思います。
Xamarin.Android 化の結果
とりあえず Unity 側の Activity (MainUnityActivity) を起動しようとすると応答なしになり最終的に強制終了になります。元々の Java 版では問題ないですし、 Xamarin.Android で単純な Activity の切り替えは問題ないので UaaL と Xamarin の組み合わせが原因とは思うのですが追及が難しくて断念しました。
おわりに
当初はサンプルが動いたらそこからいろいろやってみようと考えていたのですが、一番最初で躓いてしまいました。時間をかければなんとかできそうな感じもしなかったので・・・ もっと低レイヤーなところでデバッガ実行できればなにかわかるかもしれないですが難しいですかね。
Unity と同じ C# でローカル実行とはいっても実行空間は分断されているので Xamarin であるメリットはほぼないのですが、 Xamarin.iOS と合わせて Xamarin.Forms から扱えるとよいかもですね。
Discussion