UnityとネイティブAndoridを組み合わせたアプリを作る:前編

こんにちは、ひじかたです。

 

/* ここからオタク語り */

近頃はブルーアーカイブというゲームにハマってます。

最近メインストーリーに新しいシナリオが追加されたんですが、それがとても良かったです。

↓告知PV。1:27からBGMが変わって急にカッコいい雰囲気になるのが大好き。あと最後のネルとアリスがゲーセンでゲームしてるキービジュアルマジで好き。

後編は特に僕の推しキャラのネルがずっとカッコ良くて最高でした。ありがとう偉大なるキム・ヨンハ統括P

 

↓これ、後編の告知ツイートなんやが、キービジュアルカッコ良すぎ。最高。

-------ここからネタバレ感想-------

最初らへんのところ、アリスちゃんがミレニアムのみんなにかわいがられててとても良かった……

<Key>に人格乗っ取られてるときのアリスちゃん、正直好き。

トキに抑えられてアリスちゃんを連れていかれたことに対して、あんなのずるいって言ってるC&Cのメンバーに対して「お前らは任務でもそんなこと言うのか?」って言ってるネルカッコ良すぎ。惚れた。

アリスちゃんを取り返すのを手伝いたいけどちょっと恥ずかしいから「エンジニア部の最大の発明品を持って行ったからね。」って理由をつけて手伝うことにするウタハかわいい。そしてそれを全部説明したコトリの口を封じて「秘密は守られた」って言ってるウタハマジで好き。

アバンギャルド君をダサいとみんなに言われて「……見た目は関係ないわ。」っていっててちょっと傷ついてそうなリオ好き。でもアバンギャルド君はダサいと思う。

回線を遮断されてヴェリタスのみんながあわわわわってなってる所に”鏡”を使って助けに来てくれたチヒロ超カッコ良かった。

ボロボロなのに「この程度で諦めるのかよ」って言ってるネルマジでカッコいい。惚れた。

ネルがユズの作戦を「あたしが気に入らないわけねぇだろ?」って言ってるくだり、ネルがユズのこと認めてて好き。

トキを捕まえた時のネルのスチル、マジでカッコいい。顔が良すぎ。惚れた。

トキをエレベーターに追い詰めた時のネルの後ろ姿、カッコ良すぎ。惚れた。

「あたしの間合いに入って勝てる奴なんてこのキヴォトスのどこにもいないって。」って言ってるときのネルの顔カッコ良すぎ。惚れた。

<Key>に乗っ取られて紅い目をしてるアリス、正直好き。

世界が滅びそうなときに颯爽と現れる超天才病弱美少女ハッカー好き。

Pixel Timeの不協和音版、不穏で好き。

アリスの「アリスも!勇者になって」のところで、私たちのクエストのInstrumental Verが流れるの最高過ぎて最高。オタクこういうの大好き。

後日譚でネルの包帯にアスナが落書きしてるの、良い。

殴ったヤツの退院祝いに来るトキ、かなり良い。しかも万全の状態ならネルに勝てるって言ってるのマジで図太くて好き。早く実装されて欲しい。

最後エンディングが入るのめっちゃ良い。

-------ネタバレ感想ここまで-------

マジで好きなキャラ達が大活躍してくれてオタクもニッコリでした。

ちなみにブルーアーカイブ、前まではメインストーリーを読むのに任務というのを進める必要があったんですけど、最近の変更でそれがなくなって、無条件でストーリーが読める様になりました。Vol.3のエデン条約編の一部のストーリーだけ自分の部隊で戦闘する必要がありますが、それ以外は簡単にストーリーが読めるので今から始めるのもオススメです。

/* オタク語りここまで。 */

 

さて、オタク語りに満足したのでここまでにして、本題です。

 

 

Androidアプリのプロジェクトの構造について

今回はUnityとネイティブのAndoridを連携させてアプリを作る方法です。

 

これらを話す前にまず、少しネイティブAndroidのアプリについて解説します。

Androidアプリは基本AndroidStudioというIDEを用いて開発します。

アプリのビルドにGradleが使われており、プロジェクトファイルは以下のような構造になっています。

AndroidStudioのプロジェクトの構造

プロジェクトには、「build.gradle」ファイルと「settings.gradle」ファイルと1つ以上の「モジュール」が含まれています。

モジュールには、「build.gradle」ファイルと「src」フォルダが含まれています。

 

AndroidStudioでプロジェクトを新規作成すると、基本的には↓のような感じの構成になっていると思います。(多分こっちの方が見慣れているはず。)

基本的なプロジェクトの構造

これは「HogeHoge」というプロジェクトの中に、「app」という名前のモジュールがありますね。

そして、src内のフォルダを弄ってアプリを作ってのが基本的なアプリ開発の流れです。

 

/* これは余談 */

ちなみに、AndroidStudioでディレクトリの表示モードをAndroidにしてる時のGradle Script の中にbuild.gradleが複数あるのはこういうことです。

(上のbuild.gradleがProjectので下のはモジュールのbuild.gradle)

/* 余談ここまで */

 

話は変わって、UnityでAndroid向けのゲームをビルドする時の話ですが、実はAndroidStudioが読み込める形式のプロジェクトをエクスポートすることが出来ます。

これがUnityでAndroidStudioのプロジェクトをエクスポートしたときのプロジェクト構成です。

Unityでエクスポートしたプロジェクト

Exportedというプロジェクト内に「launcher」モジュール「unityLibrary」モジュールがあります。

このうち、「unityLibrary」モジュールがUnityで制作したゲームの本体です。後で詳しく説明しますが、UnityPlayerActivityってのが入ってます。

ちなみに、図に書かれてる「libsフォルダ」内のその他謎のファイルは、無いこともあるのでなくても気にしないでください。(Unityで特殊なSDKとかインポートしてると生えることがあります。)

つまり、こいつを自分のプロジェクトにインポートすればいい感じになります。

こんな感じでunityLibraryをインポートできると良さそう

 

UnityでAndroidStudioのプロジェクトをエクスポートする

まず、適当にUnityでAndroid向けのプロジェクトを作ります。

(作り方はググるか、僕の同期のバターさんに聞いてください。)

 

作ったら、ファイル->ビルド設定からBuild Settingsウインドウを開いて、

 

プラットフォームはAndroidで、プロジェクトをエクスポートにチェックマークを付けて、エクスポート実行します。

 

エクスポートが成功すると、こんな感じのフォルダが作成されます。

 

エクスポートしたのをインポートする

今度はAndroidStudioで適当にプロジェクトを作ります。

(作り方はググるか、僕に聞いてください。)

作ったら、File->New->Import Module でモジュールインポートウインドウが出てくるので、

 

先ほどエクスポートした「Exported」プロジェクトの中にある「unityLibrary」モジュールを選択します。

そのあとはFinishを押してしばらく待てばインポートが完了します。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

嘘です。エラーが出ます。

 

インターネットの天才さんが探してくれた解決方法によると、

note.kyokomi.dev

 

Projectの gradle.properties に以下のコードを追加します。

unityStreamingAssets=.unity3d

これで多分動きます。

 

というのは場合によっては嘘で、

今度はビルド時に、「依存してるライブラリが無いぞ」ってワーニングが出ます。

(出ないかもしれないけど次の工程はやっておくといいと思います。)

プロジェクトの「settings.gradle」を開き、多分23行目あたりにある

「include ':unityLibrary'」を「dependencyResolutionManagement」のブロックの上に移動し、「dependencyResolutionManagement」のブロック内の「repositories」内に

flatDir {
    dirs "${project(':unityLibrary').projectDir}/libs"
}

を追加します。

これは、Unity側で特殊なSDKを使ってたりすると必要な設定になります。

(なので必要ないこともあるけど、やってても多分悪影響はない。もしあったら桜の木の下に埋めてもらっても構わない。)

 

/* これは余談 */

モジュールの「build.gradle」内には「dependencies { } 」と書かれてる部分があります。これは、このモジュールがどのライブラリに依存しているかを記述する部分です。(ライブラリを使うときは大抵ここに何か書くはず。)

そこの書かれた依存ライブラリをどこから見つけてくるかを設定しているのが

「settings.gradle」の「dependencyResolutionManagement」です。今回は

「unityLibrary」モジュール内のlibsフォルダの中からも探すように設定しています。

/* 余談ここまで */

 

unityLibraryモジュールについて

Unityがエクスポートしたプロジェクト内の「unityLibrary」は、こんな感じのフォルダ構成になっています。(「ai.nreal.android.~~~~」ってフォルダは気にしないでください。これは僕が作ったUnityのアプリがNreal Ari 向けのアプリだったのであるだけで普通のプロジェクトには無いです。)

unityLibraryモジュールの構成

AndroidManifestを見てみると、UnityPlayerActivityがデフォルトで起動されるActivityになっています。中身は後で見ますが、とりあえずこのActivityを自分のアプリからstartActivityしてあげればUnityで作ったアプリをネイティブのAndroidアプリから呼び出せそうです。

 

メモ:Activityとは

Activityとは、雑に説明するとAndroidで画面を構成する一番デカい要素です。てか、画面そのものだと思ってもらっていいと思います。Activityっていうデカい枠の中にボタンやらTextView(文字のこと)やらを配置してアプリの画面が出来ます。で、Activityを切り替えて画面遷移とかが出来るってわけです。

(まあ、最近はFragmentとかいうのとNavigationとか使って画面遷移とかしてたりとかするんですが、今回は使わないのでActivityだけ覚えててください。)

 

appモジュールからUnityPlayerActivityを呼び出す

まず、appモジュールの依存関係にunityLibraryモジュールを追加します。

appモジュールの build.gradle を開いて dependencies に

implementation project(":unityLibrary")

を追加します。

 

android { } の defaultConfig { } に

ndk {
    abiFilters 'armeabi-v7a'
}

を、あと

aaptOptions {
    noCompress = ['.unity3d', '.ress', '.resource', '.obb', '.bundle', '.unityexp'] + unityStreamingAssets.tokenize(', ')
    ignoreAssetsPattern = "!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~"
}

packagingOptions {
    doNotStrip '*/armeabi-v7a/*.so'
}

を画像みたいな感じに追記します。

これが無いとUnityPlayerActivityが起動しなくて泣きながらデバッグする羽目になります。俺はキレながらデバッグした。

ではこれを、さっそく呼び出してみましょう。

こんな感じでフローティングアクションボタンを押すとUnityPlayerActivityが起動するだけのActivityをappモジュールに作りました。

(これ、JetpackComposeで書いてるから環境によってはこのコード動かないので注意)

これをビルドしてインスコして動かして、ボタンを押すとアプリが落ちます!

 


実は、このUnityPlayerActivity内でとある文字列リソースを参照しているんですが、それが無いので「リソース無いよ~ >ㇿ<」となり死にます。

なので、appモジュールのresフォルダ内のvaluesフォルダにあるstrings.xmlに以下を追記します

<string name="game_view_content_description">Game view</string>

これでようやくUnityで作ったゲームをActivityとしてネイティブ側から呼び出す事が出来ました。

とりあえずここまでで前編は終わりです。

次はUnity内のメソッドをAndroid側から呼び出したりします。

といってもここからは大体↓の記事に載ってる事なので早く知りたい方はこれを参照してください

tomo-mana.hatenablog.com

 

後編はいつ出るのか未定です。最悪忘却の彼方です。今年度中に出せるように頑張ります。