FC2ブログ
ヽ|∵|ゝ(Fantom) の 開発blog? ホーム »Unityプラグイン
このページの記事一覧

【Unity】【Android】自動バックアップの対象/除外設定をする  


 Android には自動でアプリのデータをバックアップしてくれる機能がある(Googleアカウントで Google Drive に保存される。無料で提供され、バックアップ データはユーザーの容量にはカウントされない)。デフォルトではオンになっていて、少なくとも Unity2017 の頃は何もしなくても入っていたのだが、Unity2018 以降ではマニフェストには入ってないようだ。まぁ、入って無くても、通常はオンとして扱われるハズだが、Android もバージョンアップするごとにセキュリティ関連が強化・仕様変更されているので、手動で設定する方法も覚えていた方が良いかも知れない。

アプリの自動バックアップがシンプルに
自動バックアップでユーザーデータをバックアップする

 また、自動バックアップはデータが 25MB までらしいので(掲載時点)、必要なものとそうでないものを分けておいた方が良いだろう。その方法も書いておく。というより、気がついたら半年以上バックアップとられてなかったので、調べてみたらサイズオーバーで止まっていたという状態だった。なので、自分で設定しておく必要性を感じたんだけどね(笑)。

 ちなみにバックアップがとられるデータはデータベース、共有プリファレンス、アプリケーションのプライベート ディレクトリ内のその他のコンテンツで、キャッシュ用のデータは除外されるらしい(Unity での場合、Application.persistentDataPathPlayerPrefs はバックアップされ、Application.temporaryCachePath はバックアップされないと考えて良い)。

 特に画像や動画、サウンドデータ、3Dモデルなどはあっという間に 25MB を超えるので、バックアップ対象からは除外しておいた方が良いだろう(要するにメディア本体はバックアップせず、URIやメタデータなど、復元に必要な情報だけバックアップ対象にするしかない→アプリ側でその情報からメディア本体をサーバからダウンロードして復元するなど)。


(※) Unity 2018.4.4f1 / Android 8.0 で確認



■AndroidManifest.xml での自動バックアップ設定

 自動バックアップを設定する AndroidManifest.xml のタグは application タグである。Unity の場合、「Assets/Plugins/Android/」フォルダ以下に AndroidManifest.xml が置かれるので、それを適当なテキストエディタで開き、application タグ を見つけて、「android:allowBackup="true"」を入れておく(オンの場合。オフにしたいなら false)。


 もし、プラグインなど全く使ってないのなら、デフォルトでは AndroidManifest.xml は用意されていないので、フォルダを含めて自分で作る必要がある。テンプレは Windows の場合「(インストールした Unity のフォルダ)\Editor\Data\PlaybackEngines\AndroidPlayer\src\com\unity3d\player」にあり、Mac の場合「(アプリケーションフォルダ)/Unity.app/Contents/PlaybackEngines/AndroidPlayer/src/com/unity3d/player 」にあるので、コピーして手を加えれば良いだろう。詳細は公式マニュアルを参照して欲しい。

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

 ここでは簡略した例を書いておこう。

●AndroidManifest.xml に allowBackup="true" を入れ、自動バックアップを明示的にオンにする
<?xml version="1.0" encoding="utf-8"?>
<manifest ~(中略)~
<application ~(中略)~ android:allowBackup="true">
~(中略)~
</application>
</manifest>

 なお、単純に allowBackup="true" にすると問題が出る機能もあるので、以下の記事も参考にして欲しい。例えば、gcm(プッシュ通知)などを使っている場合後述する除外設定をしておかないと通知が来なくなるという問題も出るようだ(端末ごとに一意のIDのようなものが必要な場合、バックアップから除外しておかないと不具合の原因になり、セキュリティ的にも良くない)。

Android M AutoBackup機能で開発者が対応しておいた方がよいことまとめ
allowBackupの設定は適切ですか?
allowBackup が true のときに Application Class が呼ばれないことがあって困った話



■バックアップ対象/除外を指定する

 バックアップの対象/除外を設定するにはマニフェストの他に、xml ファイルを作る必要がある。xml ファイルはテキストファイルなので、適当にファイルを作って、拡張子を「.xml」にしておけば良い。ただし、Android の仕様上、「Assets/Plugins/Android/res/xml/」フォルダ直下に置いておかないといけない。またテキストエンコードは UTF-8 にしておく。


 以下は簡略した AndroidManifest.xml での書き方である。前述の例に対して「android:fullBackupContent="@xml/my_backup_rules"」を追加しただけだが、値の「@xml」が xml フォルダを表し、「my_backup_rules」がファイル名の my_backup_rules.xml に対応している(リソース用のフォルダ名は以下を参照)。

リソースの提供 - リソースタイプをグループ化する

●AndroidManifest.xml にバックアップ対象/除外指定ファイルを設定する
<?xml version="1.0" encoding="utf-8"?>
<manifest ~(中略)~
<application ~(中略)~ android:allowBackup="true" android:fullBackupContent="@xml/my_backup_rules">
~(中略)~
</application>
</manifest>

●バックアップ対象/除外指定ファイル「my_backup_rules.xml」(※名前は任意:マニフェストに合わせる。内容は適当)
<?xml version="1.0" encoding="utf-8"?>
<full-backup-content>
<include domain="sharedpref" path="."/>
<exclude domain="sharedpref" path="gcm"/>
<include domain="file" path="."/>
<exclude domain="file" path="Thumbnails"/>
<include domain="database" path="."/>
<exclude domain="database" path="local_secrets.db"/>
</full-backup-content>

 「include」は含む(※ただし、書いてないものは含まない)、「exclude」は除外(include の中から除外という感じ)となる。

 上記の例は適当なものなので、自分の環境によって書き換えて欲しいが、簡単に言えば「PlayerPrefs をバックアップ対象にするが、gcm(プッシュ通知のIDみたいなもの)は除外、files フォルダも対象とするが、「Thumbnails」以下は除外、データーベースも対象とするが、local_secrets は除外」といった感じだ。path の値は適当に置き換えて欲しい。

 それ以外には「root」(アプリプライベートフォルダ)「external」(外部ストレージ)などもあり、Android 9.0 以降なら「暗号化したもののみバックアップ」のようなこともできるらしいが、その辺りは公式マニュアルを参考にして欲しい。

Back up user data with Auto Backup - XML config syntax
Back up user data with Auto Backup - Define device conditions required for backup



 なお、バックアップを確認するには adb を使う方法、または、単純にスマホの設定画面から「Google>バックアップ」で「今すぐバックアップ」ボタンを押せばバックアップできる。しかし、以前のデータがあったりすると(特に 25MB 超えてたりすると)上手く行かないようなので、なるべく初期段階で設定しておいた方が良いかも知れない(既に自動バックアップされなくなったアプリを再び対象にする方法がググっても見つからないんだよね…なぜかバックアップ削除してもダメなものあるし…|||orz)。





(関連記事)
【Unity】PlayerPrefs, persistentDataPath, temporaryCachePath の保存場所(パス)一覧表
【Unity】Firebase のプッシュ通知と FantomPlugin の共存(Firebase と他のプラグインの共存方法)
【Unity】Android アプリでパーミッション(権限)要求をする
【Unity】AssetStore版 FantomPlugin のセットアップ


関連記事
スポンサーサイト



category: Unity

thread: ゲーム開発

janre: コンピュータ

tag: Unityプラグイン  Unityリファレンス 
tb: 0   cm: --

【Unity】Unity2019.3 で Android / iOS ネイティブの構成が変わるらしい  


 Unity Asset Store にプラグインを出していることもあって、デベロッパーのメルマガで Unity2019.3 の大きな変更点が送られてきた。

 どうやら今までの Unity での Android / iOS ビルドの際のネイティブの構成が変わるらしい。

 まぁ、自分でプラグインなど作ったりしない場合はあまり関係ないと思うが、Unity2018.2 からは Android も Java コードをそのままビルドできるようになったので、ネイティブを使う人なら知っておいた方が良いだろう。

 詳細は公式のフォーラムを見た方が良いと思うが、例えば Android では 2019.3 で以下のような構成になるようだ。


Using Unity as a library in native iOS/Android apps


 また、Unity2019.3 からは今までと違って、ランチャーを挟んで本体の起動できるようだ。複数のアクティビティを使わないなら、あまり必要もないかもだが、例えば通常のアプリでの画面と Unity での 3Dモードで開くなど、今までより簡単にできるかも知れない。ただし『アンロードボタンは、単にアクティビティを破棄するのではなく、実際にアプリを終了します』とあるね。これも公式のフォーラムを見た方が良いだろう。


Integration Unity as a library in native Android app


 まぁ、見た感じ私の提供しているプラグインはそのまま動きそうな気がするが、確認が取れるまで、Unity2019.3 以降ではフィルタされるようだ(メルマガに書いてあった)。


 Unity の GUI も Flutter ライクのワークフローで開発できるパッケージも提供され始めたしね。UIWidgets は UIを1ドローコールで60fps以上の高効率でレンダリングできるらしいし、ネイティブのような画面遷移できるらしい。動画観てみると Unity とは思えない画面だね(笑)。


UIWidgets (Asset Store)
UIWidgets (github)
【Unity提供アセット】FlutterライクのワークフローをUnityで実現!強力なUIプラグインパッケージが新登場。60fps以上のレンダリング効率、クロスプラットフォーム対応。1ドローコールで描画する「UIWidgets」


 以上の情報からもネイティブ統合は今後強化されるかもね。





(関連記事)
【Unity】Unity2019 の StandardShader の処理が少し変わったらしいよ
【Unity】Unity2018.3.2 にアップグレードすると見た目がおかしくなることがある
【Unity】Android アプリでパーミッション(権限)要求をする
【Unity】IncrementalCompiler でのエラー:Unloading broken assembly Packages/com.unity.incrementalcompiler/Editor/Plugins/Unity.PureCSharpTests.dll, this assembly can cause crashes in the runtime
【Unity】Unity2018 でビルドエラー「CommandInvokationFailure: Gradle build failed.」が出る



関連記事

category: Unity

thread: ゲーム開発

janre: コンピュータ

tag: Unityプラグイン  Unityオープンソースライブラリ 
tb: 0   cm: --

【Unity】Firebase のプッシュ通知と FantomPlugin の共存(Firebase と他のプラグインの共存方法)  


 ちょっと最近 VRM Live Viewer に構いっきりで(笑)、FantomPlugin の更新の方が滞っているのだが、Android 8.0 以降では通知システムも変わってしまったので、試しに Firebase のプッシュ通知をオーバーライドできるかやってみた。結果はそれほど難しく無く可能だったので、細かい部分はカスタマイズした方が良いと思うが、導入もできると思う。あくまで簡単な例となるが、FantomPlugin と Firebase の共存の方法を提供しておこう。

 ただ、この機能は Unity2018.2.x 以降のプロジェクト内で Java をプラグインとして扱えるようになったおかげで使えるようになったものなので、必要であれば、以下の記事も参照して欲しい。

【Unity】【C#】プロジェクト内で Android(Java)プラグインをビルドする


(※) Unity2018.3.5f1 (Unity 2018.2 以降) / Firebase SDK 5.5.0 / Windows10(x64) で確認



■プラグインの導入

 大まかには Firebase SDKFantomPlugin の2つを用意することになる。といっても、ここではオーバーライドするプラグインの例に FantomPlugin を使っているというだけで、考え方さえわかれば、他のプラグインに Firebase を利用することも可能だろう。



●Firebase SDK のインポート(掲載時点 SDK ver.5.5.0)

 Firebase のプッシュ通知を利用するには、公式から配布されている Unity 用のパッケージを導入する必要がある。以下のページに「SDK をダウンロード」というボタンがあるので、クリックして zip をダウンロード→解凍して欲しい。

Unity プロジェクトに Firebase を追加する


 zip を解凍すると、「dotnet4」というフォルダがあるので、その中から「FirebaseMessaging.unitypackage」をインポートしよう。これには Firebase からプッシュ通知を受け取るアクティビティやマニフェストファイル、API などが含まれている。初回のインポートでは依存関係のライブラリを自動導入するので、結構時間かかるかも知れない(※Build Target が Android になってない場合はここでやっておくと良い)。また、「dotnet3」にも同じものが入っているが、これは .NET 3.x 時代のもので、Unity2018 ではデフォルトで .NET 4.x となっているので、ここでは不要だ。

 Resolver(依存関係の解決)が終わったら、大量のファイルが「Assets/Plugins/Android」に配置されていると思う。Firebase を既存のプロジェクトに使うだけなら、ここにある「AndroidManifest.xml」はあまりいじる必要はないが(だいたい自動でやってくれる)。他のプラグインと共存するには少し手を加える必要がある。その辺りは後で説明しよう。



●FantomPlugin のインポート

 とりあえず今回はアセットストア版の「FantomPlugin (Android Native Dialogs and Functions Plugin)」(※長いので略してるだけ(笑))を使って説明しよう。Google Drive 版を使っている人でも基本的には同じなので、パス名などを置き換えてもらえばできると思う。

 より詳しいセットアップは「AssetStore版 FantomPlugin のセットアップ」の記事にも書いてあるが、簡単な方法としてはエディタ上で [Ctrl+9] でアセットストアを開き「Android Native Dialogs and Functions Plugin」を検索すれば、すぐに出てくると思うので、とりあえずダウンロード→インポートして欲しい。





■FantomPlugin オーバーライド用 Acrivity の導入

 インポートが終わったら、もう1つプロジェクトに追加して欲しいものがある。それは先ほど保留したAndroidManifest.xml」 に関わる問題でもある。というのは Firebase SDK のインポート で作られたマニフェストファイル(AndroidManifest.xml)は Firebase 専用となっている。この辺りの説明は少し難しくなってしまうのだが、なるべく簡単に説明すると、この「Firebase 専用のものをオーバーライドすることにより、他のプラグインの機能を共存してしまおう」ということだ。そのオーバーライドするのに必要な Activity を用意した。そのうち、アセットストア版にも出すつもりだが、とりあえずは先行配布としてこれを使って欲しい。


 ダウンロードして zip を解凍すると「Firebase」フォルダに「OverrideFantomPluginOnFirebaseMessagingActivity.java」というのが入っていると思う。これは現在使われている「FantomPlugin」と同じもので、Unity2018.2 のプラグイン用の Java コードをプロジェクト内でビルドするために作ってみたものだ(内容的にはプラグイン「fantomPlugin.aar」の内部に入ってる「FullPluginOnUnityPlayerActivity」と全く同じ)。


 また、「AndroidManifest_FirebaseMessaging.xml」というのも入っているが、これは Firebase の「AdnroidManifest.xml」に「OverrideFantomPluginOnFirebaseMessagingActivity」をオーバーライドするように修正したものだ。Firebase のデフォルト設定に追加しただけのものなので、必要あれば編集した方が良いかも知れない。

 これらをプロジェクトのプラグインルート「Assets/Plugins/Android/」以下に置いて欲しい。ここに Java ファイルを置いておけば Unity が自動でビルドしてくれる(Build System が「Gradle」のときのみ[※Unity2018 はデフォルト])。

 また、元の「AndroidManifest.xml」はリネームして「AndroidManifest_old.xml」とでもしておき、「AndroidManifest_FirebaseMessaging.xml」を「AndroidManifest.xml」にリネームすると、オーバーライドが有効になる


 この辺りの内容は少し難しくなるので、簡単に説明にしておくと、「UnityPlayerActivity(Unity)継承→ MessagingUnityPlayerActivity(Firebase)継承→ OverrideFantomPluginOnFirebaseMessagingActivity(FantomPlugin)」のようにオーバーライドされていることになる(※つまり自作するときは同じように、競合しないようなオーバーライドする Activity を作れば良い)。

 必要なら参考資料を載せておこう。ダウンロードした zip の中の「Default」フォルダがあると思うが、その中にある「OverrideFantomPluginOnUnityPlayerActivity.java」はデフォルトの「UnityPlayerActivity」を継承している。Firebase のオーバーライドと同じように継承するものを変更すれば、他のプラグインもオーバーライドできるかも知れない。

UnityPlayerActivity Java コードの拡張
Activity
アプリ マニフェスト



■Firebase の準備

 アプリ方の準備はだいたい終わったので、次のプッシュ通知を送信する Firebase自体をセットアップしよう。

1.Firebase をまだ利用してない人は、まずは登録しよう。といっても Google アカウントを持っていれば、サイトに行けばすぐに新規登録できると思う。登録完了したら、いつでも画面の右上あたりにある「コンソールへ移動」があるので、プロジェクト管理へ移動できる。


2.コンソール(「Firebaseへようこそ」)へ来たら、プッシュ通知を利用するプロジェクトを作成しよう。「+プロジェクトを追加」を押して、プロジェクト名などを任意に入力し、「プロジェクトを作成」ボタンを押せば良いだけだ。完了したら、プロジェクトへ移動しよう。



3.初回の場合、プロジェクトにはアプリが追加されてないので以下の画面が出ると思う。今回は Android のプラグインをオーバーライドする実験なので、Android のアイコンを押そう。



4.「アプリの登録」の「Android パッケージ名」は Unity の Identification と合わせておく必要がある(※以下のアプリIDは例なので、自分のアプリのIDに置きかえる)。Unity の PlayerSettings(File>Build Settings...>Player Settings...>Other Settings>Identification)を開いてコピペすると良い。ここが1文字でも間違ってたら、通知は届かないので注意しよう。



●Unity 側

※FantomPlugin を使う場合、Android 4.2 以上にする必要がある。


5.これら Firebase の設定を Unity に認識させるために、設定ファイル「google-services.json」をダウンロードしておく必要がある。このファイルは Unity の Assets 直下に置くことで反映される(ID の紐づけ)



●Unity 側


6.次の「Firebase SDK の追加」は Unity の場合、自動でやってくれるので必要ない。



7.最後の「アプリを実行してインストールを確認」はスキップしてしまって良いだろう。





■アプリをビルドする

 これまでの準備が整ったらアプリをビルドしてみよう。注意すべき点は、「OverrideFantomPluginOnFirebaseMessagingActivity.java」「AndroidManifest_FirebaseMessaging.xml(AndroidManifest.xml)」「アプリのID(Android パッケージ名/Identification)」「google-services.json」だ。結構大変だが、置く場所なども含めて確認して欲しい。

 確認が取れたら、ビルドするシーンは何でも良いが、FantomPlugin のデモなら、「FantomPlugin/Demo/Scenes/」以下に置いてある。それらを「Build Setting>Scenes In Buildに追加し、「Player Settings...」で「Minimum API Level」が 4.2 以上(※これは FantomPlugin の仕様。できれば 5.0 以上の方が良いかも知れない)になってればOKだ。ビルドして一度起動してみよう。また、今回は通知を受信する実験をするだけなので、アプリはすぐに終了して構わない。







■Firebase からプッシュ通知を送る

 ここまででの手順が間違ってなければ、既に Firebase からプッシュ通知の送信ができるようになっている。Firebase のコンソール へ行き、左のメニューから「Cloud Messsaging」へ移動しよう。初回なら「Send your first message」のボタンが出るので、それを押すとメッセージを作成することができる。



1.通知の作成画面では任意にテキストを入力して行こう。気をつけて欲しいのは既にリリースされているアプリの場合、適当に入力したものがユーザーに届いてしまうことである。その辺は自己責任で(笑)。



2.一番重要なのは、このターゲットのアプリ(ID)だ。ここを Unity のアプリの Identification と同じにすることによって、そのアプリ用の通知として送られる。間違えないようにしよう(Android / iOS などでも分別できる)。



3.以降の「スケジュール設定」は「Now」(今すぐ)で、「コンバージョンイベント」はデフォルトで良いだろう。「その他のオプション」では「Android 通知チャンネル」という項目があるが、これは Android 8.0 以降の「通知チャンネル」の機能で、通知ごとに種類を分別できるようにするものだ(例えば「お知らせ」とか「更新情報」とか、別々に通知のオン・オフできるようにするため)。Android 8.0 より前の機種では分別はされない。

Android O(APIバージョン26)のPush通知



4.最後の「メッセージの再確認」では「公開」ボタンを押すと即送信されるので(スケジュールで「今すぐ送信」(Now)の場合)、間違いがないか確認してから押そう。ユーザーに飛んでいってしまうので、もう取り消せない(笑)。



5.履歴が表示されていれば、送信完了だ。通信状態・サーバー状況などによって、タイムラグが出ることもあるが、成功していればおおよそすぐに通知が来ると思う。実機で確認してみよう。





※アイコンは Unity で設定したものが表示される(空だと Android のデフォルトアイコンになる)






(関連記事)
【Unity】【C#】プロジェクト内で Android(Java)プラグインをビルドする
【Android】【Java】パーミッションの付与(許可)のチェックと要求をする
【Unity】Androidのトーストやダイアログ、通知、音声認識、ハード音量操作など基本的な機能を使えるプラグインを作ってみた
【Unity】AssetStore版 FantomPlugin のセットアップ


関連記事

category: Unity

thread: ゲーム開発

janre: コンピュータ

tag: Unityライブラリ  Unityプラグイン  Unityオープンソースライブラリ  Firebase  FantomPlugin 
tb: 0   cm: --

【Unity】【C#】プロジェクト内で Android(Java)プラグインをビルドする  


 Unity 2018.2 の新機能として『Unity プロジェクト内で .java および .cpp のソースファイルがプラグインとして使用可能に』と書いてあったので試してみた。

 私も Androidネイティブプラグインをアセットストアで配布しているが、どちらかというとオールインワン的なプラグインとなってしまったので、これ以上追加すると使わない機能の分もファイルサイズが増えてしまうので、どうしようかと考えていたところだ(笑)。

 なのでタイミング的にもちょうど良かったかも知れない。Unity 2018.2 から導入された、プロジェクトに Java を内包して Grandle でビルドする方法を使えば、1つ1つの欲しい機能だけを追加することもできる。特にスマホのようなメモリもストレージも容量が小さいデバイスは、無駄にファイルサイズを増やさないで済むので重宝されそうだ。

 やってみた感想は、とても簡単で特につまづくことも無かったが、Java のコードに手を加える分にはやはり Android Studio で編集した方が良いかも知れない(どのみち Android SDK はインストールしなくてはならないし…)。また、単純にコードやインポートのチェック、エラーのデバッグも必要だしね。ただ、既に動作確認とれている Java コードなら、Android Studio を開かないで多少の手直しなどはできるから、かなり便利だ(笑)。

 とりあえず今回は Android ビルドの環境が整ってる状態でのコード作成やビルドの方法となるので、環境構築が必要な場合は、資料となる記事などを掲載しておくので、参考にして欲しい。また、Android Studio でコードを書く際での参照設定もついでに書いておこう。これらはバージョンによって大幅に仕様変更される可能性が高いので、できれば常に最新の情報を検索して確認するようにして欲しい。

(Android ビルドのための環境構築など)
[Unity初心者Tips]SDKはここでした!AndroidでBuildする方法2018の10月版
Android Studio のインストール


(※) Unity 2018.2.1f1 / Android Studio 3.1.3 / Windows10(x64) / Galaxy S7 Edge (Android 8.0) で確認



■Android プラグインを Java で書く

 Java のコードは何らかのテキストエディタでも Android Studio を使っても良い。ただ Android Studio で書く場合は多少、参照設定など環境構築が必要なので、それらは「Android Studio で Unity プラグインを作る際の参照設定など」を参照して欲しい。

 とりあえず今回は Android の トースト機能(戻値なし)と、int型の値を受け取る実験として、プラグインからビルドバージョンを取得する(戻値あり)プラグインを書いてみよう。

●プラグイン定義:Java (Android) 側のコード(AndroidPluginSample.java)
package com.sample.myapplication;

import android.os.Build;
import android.widget.Toast;
import com.unity3d.player.UnityPlayer;

public class AndroidPluginSample {

//トースト用コード
public void ShowToast(String message, boolean longDuration) {
Toast.makeText(UnityPlayer.currentActivity,
message,
longDuration ? Toast.LENGTH_LONG : Toast.LENGTH_SHORT)
.show();
}

//ビルドバージョン取得用コード
public int GetBuildVersion() {
return Build.VERSION.SDK_INT;
}
}

 Java コード自体の解説は割愛するので、必要あればググって欲しい(難しくはないのですぐに理解できると思う)。今回この2つを用意したのは、戻値ありのメソッドと戻値なしのメソッドを試してみたかったからだ。実際これらができれば、プラグインでやりたいことは大抵できると思う。ちなみに Unity のシステムと Android のシステムは別物として動いてると考えて良いので、データの受け渡しをする際には基本的にプリミティブ型中心となる。複雑なパラメタを持つクラスなどをやりとりしたい場合は、共通のプリミティブ型で作ったクラスを定義するとか、JSON などにして文字列型で渡すのが良いだろう。

 ちなみに私が提供しているプラグインは JSON でやりとりしてる。本当はプリミティブ型だけでやりとりした方が高速だとは思うが、パラメタを増やしたり、仕様変更したりするときなどの保守が大変になってしまうのと、何より JSON に関しては Unity でも Android でも簡単に利用できるビルトイン機能があるので、非常に楽に扱えるメリットがあるからだ(JSON はただの文字列型なので、データの加工・流用がしやすい)。高速性や保守性を考えて、どちらを使うかを選択するのも良いだろう。

 この Javaコードが書けたら、Unity のプロジェクトビューで Assets 直下に「Plugins/Android」フォルダを作ろう。ここに Java ソースを置くことにより、Unity がビルドする際に一緒にコンパイルされる(Build System が「Gradle」のときのみ)。





■Unity から Android プラグインを利用する C# コード

 上記の Java コードを書いて、プラグイン用フォルダに配置したら、次に Unity から利用する C# コードを書いてみよう。

 今回の例では Unity 上で UI ボタンを置き、それを押すことにより、トースト表示とビルドバージョンの取得をしている。UI などのコールバック設定方法などは以前の記事にまとめてあるので参照して欲しい。簡単に言えば、Button の場合はインペクタで「On Click()」に以下のコードの「OnClick()」を登録すれば良いだけだ。面倒なら UI を使わずに「Start()」から直接「OnClick()」を呼ぶようにしても良い(ただし起動時にいきなりだと、確認しずらいと思うが(笑))。

UnityEvent, Action, delegate, interface でのコールバック実装方法とインスペクタでの登録


●プラグイン呼び出し:C# (Unity) 側のコード(JavaPluginTest.cs)
using UnityEngine;

public class JavaPluginTest : MonoBehaviour {
// Use this for initialization
private void Start () {
//OnClick(); //ここから呼んでも良い
}

const string PLUGIN_PACKAGE_NAME = "com.sample.myapplication.AndroidPluginSample"; //ここは Java で作った package 名と class 名に合わせる

//Button.OnClick などから呼ぶ
public void OnClick()
{
//ビルドバージョンの取得テスト
int buildVersion = 0;
using (var JavaPlugin = new AndroidJavaObject(PLUGIN_PACKAGE_NAME))
{
buildVersion = JavaPlugin.Call<int>("GetBuildVersion");
}

//トーストの表示テスト
using (var JavaPlugin = new AndroidJavaObject(PLUGIN_PACKAGE_NAME))
{
JavaPlugin.Call("ShowToast", "テストだよん\nBuild Version : " + buildVersion, true); //buildVersion が取得できなかったときは 0 となる
}
}
}

 注意点は定数「PLUGIN_PACKAGE_NAME」(名前は任意)で先に作った Java の package 名と class 名を繋いでフルパスで指定する点だ。このパッケージ名はアプリ自体のパッケージ名(Bundle Identifer)とは別でも構わない。他のプラグインを利用することも考えて、自作するときには世界で唯一の名前にしておこう("com.sample.myapplication" は良くない例(笑))。この Java での package(パッケージ名)とは C# で言う namespace に近いものなので、ユニークにしておけば、同じクラス名があっても大丈夫だ(なので絶対パスで指定する必要がある)。Java の場合パッケージ名の区切り文字(ドット:".")はフォルダ名と同義になるので、実際にパス名となる(ドット:"." を "\" や "/" に置き換えたパスに格納されている。C# の場合はパスになってなくても良い)。


 あとは「Build Settings...」にテストするシーンを入れて「Build System」を「Gradle」にしてビルド(Unity2017以降はデフォルト)するだけだ。実機で確認してみよう。まだ環境構築ができてない場合は、以下の資料を参考にして欲しい。

(Android ビルドのための環境構築など)
[Unity初心者Tips]SDKはここでした!AndroidでBuildする方法2018の10月版
Android Studio のインストール


●Build System は「Gradle」にする(Unity2017 以降はデフォルト)


●実機ではボタンを押すとビルドバージョンがトーストで表示される




■Android Studio で Unity プラグインを作る際の参照設定など

 意外と Android プラグイン作成でつまづくのは Android Studio の環境構築(特に Gradle)だ。この辺りは導入しているバージョンによって違うので、上手く行かなかったら、自分が使っているバージョンも含めてググって欲しい。ここではあくまでも私が上手く行った設定方法を書いておく。特に Gradle に関しては 2.x と 3.x では書き方も違うので、Android Studio を 2.x から 3.x にアップデートしたときなどは、いっそのこと環境を再構築した方が良いかも知れない(私も大量のエラーやアップデートで不具合が出たため、新規インストールから再構築した経験がある)。

 また、私の環境では、SDKのビルドツールのバージョンなども Android 7.0 まで対応の場合は Android SDK Platform-Tools 27.x.x で、Android 8.0 以降対応では Android SDK Platform-Tools 28.x.x でビルドしないと上手く行かなかった。組み合わせもあるかも知れないので、原因不明のビルドエラーが多発するなら、その辺りも見直した方が良いだろう。

 Android Studio で Unity 用のプラグインを作成する場合、インポート文「import com.unity3d.player.UnityPlayer」が必要になる(参照設定してない場合、エラーが出てると思う)。これはインストールした Unity の以下のフォルダに「classes.jar」があるので、Android プロジェクト内の「libs」フォルダにコピーし、参照設定すれば良い。そこまでやってみよう。

(公式から抜粋)
Unity に付属の classes.jar を見付けてください。これは、インストールフォルダー(通常 C:\Program Files\Unity\Editor\Data [Windows] または /Applications/Unity [Mac]) のサブフォルダーである PlaybackEngines/AndroidPlayer/Variations/mono または il2cpp/Development or Release/Classes/ 内にあります。次に、新しいアクティビティのコンパイルに使用されるクラスパスに classes.jar 追加します。アクティビティのソースファイルをコンパイルして JAR または AAR パッケージに含め、それをプロジェクトフォルダーにコピーしてください。


1.(Windows の場合)「(Unityをインストールしたフォルダ)\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\il2cpp\Release\Classes」をエクスプローラで開くと「classes.jar」がある。それを右クリックで「コピー」し、Android Studio に戻り、プロジェクト内の「libs」フォルダに右クリックで「Paste」する。



2.メニューから「File>Project Structure...」を開き、左のペインで現在のプロジェクト(Modules)を選択し、「Dependencies」タブに切り替えたら、右にある「+」ボタンをクリックし、「Jar Dependency」を選択する。



3.「Select Path」ダイアログが出たら、先ほどコピーした「libs/classes.jar」を選択し、OKを押す。



4.これで Unity(プレイヤー)への参照設定が追加されたので、「Scope」を「Complie only」にしておく(※今回はあまり必要ないが、Android Studio で aar などをビルドしたくなったとき、あった方が良い)。




 一応、今回のように Unity のみでビルドする際には上記まででもOKだが、Android Studio で aar などをビルドしたくなったときは Gradle 設定に以下の文を入れておくと良い。


●build.gradle (モジュールごとにあるので注意)
・・・(略)・・・

dependencies {
//implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation fileTree(include: ['*.jar'], exclude: ['classes.jar'], dir: 'libs')
・・・(略)・・・
}

 「dependencies」部分に元からあった「implementation fileTree(include: ['*.jar'], dir: 'libs')」をコメントアウトして、「exclude: ['classes.jar']」を入れた文に書き換えておこう。これはビルドする際「classes.jar」自体は含めないという設定だ。開発中は参照する必要があるが、リリースする際には Unity 本体に含まれているので、この除外設定がないと2重にライブラリがインクルードされる(ファイルサイズも無駄に増える)。ただし、Android Studio でビルドせず、Unity だけでビルドするなら、この設定は必要ない(あくまでも念のため)。

 この辺りはバージョンによって書き方も変わってるようなので、できればその都度確認した方が良いだろう。

 Android Studio で Java コードを書いた際は、プロジェクト内で作ったクラスを右クリックで「Copy」し、これを Unity プロジェクトの「Assets/Plugins/Android/」フォルダ以下にペーストすれば良い。あとは「Build Settings...」で「Build System」を「Gradle」にすれば一緒にビルドされる。aar にビルドする必要はないので、とても楽だ。試してみよう。


●右クリックで「Show In Explorer」すると、フォルダが開かれ「~.java」が見つかるのでコピーしても良い



 実際にビルドする際には、マニフェストファイル(AndroidManifest.xml)の編集が必要になることもあるので、その辺りの資料は以下を参照して欲しい。

Android ビルドをもう少し詳しく
Android アプリでパーミッション(権限)要求をする
Android マニフェスト





(関連記事)
【Unity】Firebase のプッシュ通知と FantomPlugin の共存(Firebase と他のプラグインの共存方法)
【Unity】Androidのトーストやダイアログ、通知、音声認識、ハード音量操作など基本的な機能を使えるプラグインを作ってみた
【Unity】AssetStore版 FantomPlugin のセットアップ
【Unity】Android アプリでパーミッション(権限)要求をする


関連記事

category: Unity

thread: ゲーム開発

janre: コンピュータ

tag: Unityプラグイン 
tb: 0   cm: --

【Unity】【C#】Android で VRM(VRoid)を動的に読み込む  


 VRM Live Viewer にも利用しているが、元々は「プラグインを使って VRM を Android で読み込めるか?」という実験をしてみたら、スンナリと行けてしまったので次々とアイデアが浮かび、VRM Live Viewer をリリースするまでに至ってしまったという…(タイムスタンプを見ると、試しにライブステージ導入してから、アプリリリースまで4日しかかかってない←夢中になるといつの間にかアプリを完成させてしまうことも多い(笑))。


 まぁせっかくなので、VRMVRoid を Android でも読み込み、利用する方法を書いておこう。ちなみに VRM は VRChat やバーチャルキャストで使われるアバターフォーマットではあるが、リアルタイムで読み込むことができるので、あらかじめモデルをアプリに入れてビルドする必要もなく、読み込みもそれほど時間はかからないので、応用範囲は広いと思う。

 私は Unity4 の時代から MMD を Unity で動かしたり、一般公開されているモデルを実験で使ってたりしてたが、Unity ではいつもキャラのバリエーションが少ないな~と感じていたので、VRM で動的に読み込めるのは画期的だとさえ思う。例えば RPG でもアクションでも、好きなキャラで遊べるゲームとかも作れそうだしね(もちろん、大きさやコライダの判定などの問題もあるが、あくまで可能性として(笑))。アイデアは常に新しい発想から生まれるので、既成概念に捕らわれずに色々やってみると良いと思う。それがいつか新たな作品に繋がる。

 今回はあくまで Android で VRMVRoid を読み込む方法だけだが(どちらも "~.vrm" で扱うとして)、私が試したところ、一度 Unity 内に読み込んでしまえば、プラットフォームに関係なく扱えると思うので(見た目はシェーダなどのせいで多少変わることもあるが)、ひとつの方法として覚えておけば色々活用できるだろう。ちなみに VRM Live Viewer は Android版と Windows版を出しているが、ファイル読み込みやダイアログなどプラットフォーム固有のもの以外は全て同じだ。実際にシーン1つだけでビルドしている。つまり複数のプラットフォーム対応も簡単にできることがわかる。


(※) Unity 5.6.3p1 - 2018.2.1f1 / UniVRM 0.40 - 0.43 / VRoid Studio 0.1.1 - 0.2.8 / Windows10(x64) / Galaxy S7 Edge (Android 7.0) で確認



■UniVRM をインポートする

 Unity で VRM を読み込むには UniVRM というオープンソースが必要となる。ライセンスは「MIT License」となるので、その辺りは各自で確認して欲しい。ちなみにライセンス形態にも色々あるが、MIT License は比較的緩いライセンスだ。ついでに参考資料も載せておこう。

(参考)
GPL, LGPL, BSD などのOSSライセンスの違いと注意点まとめ
知らないと損をする6つのライセンスまとめ



 なお、新規プロジェクトで Android プラットフォームでビルドして試すなら、パッケージをインポートする前に「File>Build Settings...」であらかじめ「Switch Platform」で Android プラットフォームに切り替えておいた方が良いかも知れない。UniVRM に内包されているシェーダ(MToon 等)を再コンパイルしたりするのに結構時間がかかる(笑)。


 プロジェクトの準備ができたら、まずは UniVRM をダウンロードしよう。今回はアプリに動的に VRM を読み込むので UniVRM の本体「UniVRM-x.xx_xxx.unitypackage」(xxx はバージョンなど)の他に「UniVRM-RuntimeLoaderSample-x.xx_xx.unitypackage」のインポートも必要になる。本体「UniVRM-x.xx_xxx.unitypackage」を先にインポートしてから、ランタイムローダ「UniVRM-RuntimeLoaderSample-x.xx_xx.unitypackage」をインポートしよう。とりあえず VRM の動的読み込みに必要なものはこれだけで良い。






●API のアップデートが促されたら、「Go Ahead!」する




■VRM を動的に読み込んでみる

 UniVRM のインポートが終わったら、次にプロジェクトビューで「Assets/VRM.Samples/Scenes」で、シーン「VRMViewer」を開いてみよう。ビューワ自体は PC 用なのだが、これを改造することにより、Android 等他のプラットフォームの読み込み方法もわかると思う。



 ちなみに「VRM Live Viewer」はこのシーンを元ベースとしている(見た目もたいして変わってないのでわかると思うが(笑))。他の VRM 利用アプリを見てみると、たぶん同じようにこれを改造してるものが多い気がする。エクスポートできるアプリを作るなら、シーン「VRMRuntimeExporterSample」あたりを見てみると良いと思う。せっかくのオープンソースなのだから、遠慮なく使わせて頂こう(笑)。


 このシーンでは左上部にある「Open」ボタンを押すことにより、VRM を動的に読み込んで、シーン上にモデル(アバター)をロードすることができる。ただ、Windows 上なら 「PC, Mac & Linux Standalone」プラットフォームになってればそのまま使えるが、Android では無視される。この辺りから少し改造していこう。


1.スクリプトとしてはヒエラルキーで「Canvas」をクリックして、インスペクタで表示される「Viewer UI」にそのコードが書かれている。これを編集しよう。グレーアウトしてる「Script>ViewerUI」をダブルクリックすれば、Visual Studio で開かれる(シングルクリックなら、プロジェクトビューで移動できる)。



2.「ViewerUI.cs」を開いたら、検索で「OnOpenClicked」を探してみよう。これが前述した「Open」ボタンのイベントハンドラとなっている。ここのコードを見てみるとプリプロセッサディレクティブ(#if~文)でプラットフォームが分けられている。とりあえず Unity エディタ上でもテストできるようにディレクティブ(UNITY_EDITOR_WIN)を付け加えておこう。

void OnOpenClicked()
{
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
var path = FileDialogForWindows.FileDialog("open VRM", "vrm", "glb", "bvh");
#else
var path = Application.dataPath + "/default.vrm";
#endif
・・・(略)・・・
}

 ちなみに「UNITY_EDITOR_WIN」とは「Unityエディタ上でかつ Windows である場合の条件」である。プラットフォーム依存コンパイルを上手く使えば、複数のプラットフォームを分別することも可能だ。まぁしかし、コードは見づらくなるので、機能まるごとみたいな場合は、クラスごとに用意するという手もある。今回は一部を改造して使うので、この方法でやっていこう。

プラットフォーム依存コンパイル


3.「UNITY_EDITOR_WIN」を入れたら、グレーアウトしていた文字が見えるようになったと思う。しかし「FileDialogForWindows.FileDialog」の方にエラーが出たかも知れない。まぁ、これも同じプラットフォーム依存なので、「FileDialogForWindows」部分にカーソルを合わせ、「F12」を押せば、クラスがまるごとグレーアウトしてるのがわかる。手順2と同じように「UNITY_EDITOR_WIN」を #if~文に追加しよう。

#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
using System;
・・・(略)・・・
#endif

namespace VRM
{
public static class FileDialogForWindows
{
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
#region GetOpenFileName
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class OpenFileName
{
・・・(略)・・・
}
・・・(略)・・・
#endif
}
}


 これでコンパイルが通るようになったと思う。一旦、Unityエディタに戻ってプレイしてみよう。「Open」ボタンを押して適当な「~.vrm」を読み込んで見ると良い。VRMニコニ立体で多く配布されているので、いくつかダウンロードしておくと良いだろう。「ニコニ立体ちゃん」ことアリシア・ソリッドはとても軽いのでテストするにはもってこいだ。自分で作った VRoid でも可能だが、髪の毛などメッシュが多いものほど、生成に時間がかかるようだ(なので「VRM Live Viewer」では非同期読み込みの方を利用している。非同期読み込みを使うには「.NET4.x」にする必要があるので、ここでは割愛)。

ニコニ立体ちゃん (VRM)





■VRM の動的に読み込みを Android に対応させる

 VRM を動的に読み込みに成功したなら、後は Android に対応させるだけだ。ファイル選択などはプラットフォームに依存するので、先に出てきた「FileDialogForWindows」のようなものが必要になるが、Unity の標準機能には無いので、ここではプラグインを使うことにする(自分で作ったものがあれば、それでも良い)。



 ここで紹介するプラグインは元々私がブログで公開していたものだが、様々なアプリで利用して貰えてるようなのでアセットストアにも提出したというものだ(既に GooglePlay 等で公開されてるアプリなどにも利用されている。「〇〇というアプリを作ってるんですが、使わせて貰って良いですか?」と聞かれるようになったので、気兼ねなしに使えるようにアセットストアにも出したという経緯もある)。AssetStore版GoogleDrive版に機能的な違いはないので(AssetStore版 はアセットストアの規約に合わせただけ)、どちらを利用しても構わない(※ここでは AssetStore版を例にしている)。



 セットアップは以前の記事にあるので、そちらを参照して欲しい。AssetStore版GoogleDrive版では一部ファイル名やパス、素材が違うくらいで、内容的には同じだ。注意点は「Plugins」フォルダを「Assets」直下に移動し、「Plugins/Android」フォルダにあるサンプルのマニフェストファイル(AndroidManifest.xml)を用意しておくということだ(テストだけなら、"AndroidManifest_demo.xml"[AssetStore版]、または"AndroidManifest_test.xml"[GoogleDrive版]を複製してリネームすれば良い)。

AssetStore版のセットアップ
GoogleDrive版のセットアップ


1.プラグインのインポートとセットアップの準備が済んだら、プロジェクトビューの検索で「StorageOpenFileController」のプレファブを見つけよう。見つけたら、これをヒエラルキーに置き、後述のコードを書くことにより、Android でもファイルの情報を受け取れるようになる。本来なら Android でストレージの読み取りなどにはパーミッションなども必要になるが、前述のデモのマニフェスト("AndroidManifest_demo.xml"など)を使ってる分には既に含まれている(「READ_EXTERNAL_STORAGE」または「WRITE_EXTERNAL_STORAGE」が必要。デモにはそれ以外の権限も含まれているが、通常は不要な権限は削除した方が良い→ユーザーにインストを拒否られる確率が高くなるため)。

※Unity2018 以降、Android 8.0 以上を対象にしている場合は、「File>Build Settings...>Player Settings...>Other Settings>Configuration>Write Permission」を「Exernal (SD Card)」にするか、「Android アプリでパーミッション(権限)要求をする」でパーミッション要求をした方が良いかも知れない(Unity2017 のときと違い、自動で出なくなった(?))。

(パーミッション)
Android アプリでパーミッション(権限)要求をする
READ_EXTERNAL_STORAGE(ファイル読み取り権限)
WRITE_EXTERNAL_STORAGE(ファイル読み書き権限)



2.次に「StorageOpenFileController」で取得したファイル名を受け取るハンドラを、元のコード「ViewerUI.cs」の「OnOpenClicked」に追加しよう。書き方は前述のコードに追加する形となる。Android の場合ディレクティブは「UNITY_ANDROID」となるので、それを追加し、「StorageOpenFileController」でストレージを開くコードを Android プラットフォーム用に書いておこう。「using FantomLib;」を入れておくことを忘れずに。

プラットフォーム依存コンパイル

using FantomLib;

・・・(略)・・・

void OnOpenClicked()
{
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
var path = FileDialogForWindows.FileDialog("open VRM", "vrm", "glb", "bvh");
#elif UNITY_ANDROID
var path = "";
StorageOpenFileController storageOpenFileController = FindObjectOfType<StorageOpenFileController>(); //ここはインスペクタで登録できるようにしても良い
storageOpenFileController.Show(); //実機ではエクスプローラのようなもので、ファイル選択ができるようになる
#else
var path = Application.dataPath + "/default.vrm";
#endif
if (string.IsNullOrEmpty(path))
{
return;
}
・・・(略)・・・
}

※この例はやっつけ的なコードなので、「StorageOpenFileController」をインスペクタで登録できるようにしたり、任意にまとめたりして使って下さい(笑)。


3.ランタイム時では「StorageOpenFileController」は閉じられてから、コールバックで結果(選択されたファイルパス名)が返ってくるので、「UNITY_ANDROID」ディレクティブ内ではパスを空(path = "")にしていることに注意して欲しい。これはすぐ下にある「string.IsNullOrEmpty(path)」で一旦終了することを意味する。

 なので、取得したパスを受け取るハンドラを作成する必要がある。ここでは簡略のため、元の「OnOpenClicked()」内のコードを一部まるっとコピーして、もう1つ「OnStorageOpenFile()」というメソッドを定義した(メソッド名は任意)。

public void OnStorageOpenFile(string path)
{
if (string.IsNullOrEmpty(path))
{
return;
}

var ext = Path.GetExtension(path).ToLower();
switch (ext)
{
case ".gltf":
case ".glb":
case ".vrm":
LoadModel(path);
break;

case ".bvh":
LoadMotion(path);
break;
}
}

※UniVRM v0.40 以前は拡張子分岐は無いが、同じように「LoadModel(path)」を呼べば良い。

 実際には「StorageOpenFileController」をインスペクタで登録できるようにしたり、拡張子による分岐などは重複してるので「OnOpenClicked() → OnStorageOpenFile(path)」へ行くように書き換えても良いだろう。その辺りはお任せする(笑)。とりあえずはコード自体はこれで良い。


4.後はヒエラルキーに戻って「StorageOpenFileController」のコールバック「OnResult」に先程の「OnStorageOpenFile(String)」に登録しよう。これで一応完成である。ただし、実機でしか確認できないので、Android ビルドして動作確認してみよう。



5.「File>Build Settings...」を開いてシーン「VRMViewer」を追加してビルドしよう。ビルドに関してはいくつか注意点があるので、以下を参照して欲しい。

「要求 API Level」の設定
シーンを追加してビルドする
Unity 2018.1.0~1.6 での Gradle ビルドにおいて、「Cannot read packageName from~(パス)\AndroidManifest.xml」と出る。




 ここまでできれば、例えば以前の「VRoid(VRM)を動かす」のようにして、ゲームに使うことも可能だろう。1つ1つの技術は結構手間のかかるものだと思うが、プラグインも含め、全て無料でできるので、これを使わない手はない(笑)。今までにない新たな利用法を考えてみるのも良いだろう。

●実機(Android)で「ニコニ立体ちゃん (VRM)」を読み込んでみた所

ニコニ立体ちゃん (VRM)
(c) DWANGO Co.,Ltd. ニコニ立体ちゃんライセンス


 今回はただ VRM を読み込んで動的にアバターを召喚(笑)しただけだが、実際にスマートフォンで利用するには画面解像度・回転の対応やピンチなど、使い勝手を良くした方が良いだろう。プラグインにはそういったスマホらしい操作(ピンチ・スワイプ・ロングタップ等)の例も入っている。VRM Live Viewer の Android 版はまさにその使用例なので、動作確認にインストして動かしてみるのも良いだろう(またはプラグインのデモもQRコードからインストできるようにしてあるので参考に)。











(関連記事)
【Unity】VRM(VRoid)をライブステージで踊らせるアプリを作ってみた
【Unity】VRoid(VRM)をインポートして動かす
【Unity】Unity2018.3.2 にアップグレードすると見た目がおかしくなることがある
【Unity】AssetStore版 FantomPlugin のセットアップ
【Unity】Androidのトーストやダイアログ、通知、音声認識、ハード音量操作など基本的な機能を使えるプラグインを作ってみた


関連記事

category: Unity

thread: ゲーム開発

janre: コンピュータ

tag: VRM  VRoid  Unityオープンソースライブラリ  Unityプラグイン  C# 
tb: 0   cm: --


プロフィール

Social

検索フォーム

全記事一覧

カテゴリ

ユーザータグ

最新記事

リンク

PR

▲ Pagetop