- 2019/02/25 【Unity】Firebase のプッシュ通知と FantomPlugin の共存(Firebase と他のプラグインの共存方法)
- 2019/01/14 【Unity】Android アプリでパーミッション(権限)要求をする
- 2018/07/26 【Unity】【C#】テキストファイルの読み書きをする(リソース/ストレージ)
- 2018/07/04 【Unity】【C#】動的にオーディオファイルの読み込みと再生をする
- 2018/05/29 【Unity】スマホで簡易360度(パノラマ, 全天球)ビューワを作る
【Unity】Firebase のプッシュ通知と FantomPlugin の共存(Firebase と他のプラグインの共存方法) 
2019/02/25 Mon [edit]
ちょっと最近 VRM Live Viewer に構いっきりで(笑)、FantomPlugin の更新の方が滞っているのだが、Android 8.0 以降では通知システムも変わってしまったので、試しに Firebase のプッシュ通知をオーバーライドできるかやってみた。結果はそれほど難しく無く可能だったので、細かい部分はカスタマイズした方が良いと思うが、導入もできると思う。あくまで簡単な例となるが、FantomPlugin と Firebase の共存の方法を提供しておこう。
ただ、この機能は Unity2018.2.x 以降のプロジェクト内で Java をプラグインとして扱えるようになったおかげで使えるようになったものなので、必要であれば、以下の記事も参照して欲しい。
・【Unity】【C#】プロジェクト内で Android(Java)プラグインをビルドする
●Firebase SDK のインポート
●FantomPlugin のインポート
■FantomPlugin オーバーライド用 Acrivity の導入
■Firebase の準備
■アプリをビルドする
■Firebase からプッシュ通知を送る
(※) Unity2018.3.5f1 (Unity 2018.2 以降) / Firebase SDK 5.5.0 / Windows10(x64) で確認
■プラグインの導入
大まかには Firebase SDK と FantomPlugin の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【Unity】Android アプリでパーミッション(権限)要求をする 
2019/01/14 Mon [edit]
もしかしたら Unity2018.3.x のバグかも知れないが、Android ビルドした際に、パーミッション(権限)要求が自動で出なくなったので、「一部機能が使えない」等のトラブルが結構出てるのではないかと、改めて記事を書いてみた。

公式のデベロッパーサイトにも掲載されているが、Android 8.0 ではパーミッション付与の仕様(どちらかというとガイドライン)も変更されたようで、今まではアプリ起動時に権限要求が自動で全て表示されてたけど、Android 8.0 以降では、その機能を利用するときに権限を要求しましょうということになっている(不要な権限やセキュリティに関わる権限をなるべく減らし、ユーザーにとって許可する内容をわかりやすくするため)。
・Android 8.0 での動作変更点>パーミッション
・実行時のパーミッション リクエスト
冒頭に書いた「バグかも知れない」というのは、Unity でアプリビルドした際には自動で起動時に権限要求が表示されていたからだ。Android 開発では Android 6.0 以降、その機能は実装されているが、Unity のみ開発している人にとっては、割と敷居の高い設定項目となる(公式にも「上級レベルの Android 開発者にのみ推奨」とある)。そのうち、Android ビルドで権限要求の選択ができるようになるかも知れないが(例えば PlayerSettings>Other Settings>Configuration>Write Permission を「External (SD Card)」にすると、書き込み権限が自動的に要求される)、とりあえず現在の状態ではそういう機能はないので、プラグインを使って権限要求する方法を書いておこう。
なお、今回の記事はプラグインのデモも兼ねている。サンプルシーンを使えば1から構築する必要はないので、すぐに試してみたい人はプラグインをダウンロードして欲しい。AssetStore版[無料]とGoogleDrive版の2つがあるが、基本的にはどちらも同じものだ。好きな方で構わない。
プラグインデモをダウンロード


Android 4.2以上
※「提供元不明アプリのインストール」許可が必要です。
プラグイン自体のセットアップは以前の記事を参照して欲しい(>>GoogleDrive版 | >>AssetStore版)。デモが入っているパスは GoogleDrive 版では「Assets/_Test/」に、AssetStore版は「Assets/FantomPlugin/Demo/」となっているので適宜置き換えて欲しい。ファイル名は基本的に同じだ。
■プラグインのセットアップ(AssetStore 版) [※別ページ]
■PermissionCheckController を配置と使い方
■AndroidManifest.xml を設定する
(※) Unity 2018.3.1f1 / Windows10(x64) で確認
■PermissionCheckController を配置と使い方
実際、以前の記事にも書いたのだが、パーミッション要求というのは通常ネイティブで書くしかないので、Unity で利用するには非常に困難である。なので、誰でも手軽に使えるようにプラグインとして導入しておいた(プラグインの中身も以前の記事とほぼ同じ)。その使い方を簡単に説明しておこう。
「PermissionCheckController」はプレファブとスクリプトで提供している(FantomLib/Prefabs/System/ 以下 ※検索で探すと楽)。これをシーンにドラッグ&ドロップで配置しよう。配置したら、以下の項目を設定すれば完了だ。


※ここではデモシーン「ExternalStorageTest」の「AndroidFunctions」に入っているプレファブを使っているが、
基本的に同じものである(説明ダイアログ付きのデモとなっている)。
Permission | 要求する権限の文字列定数。この文字列定数は公式のデベロッパーサイトに掲載されている「Constant Value」の値を指定する。例えばカメラの権限なら「android.permission.CAMERA」を入れる。基本的に "android.permission.~" で始まる文字列となる。 |
---|---|
Check On Start | Unity のライフサイクル Start() で自動的にパーミッションのチェックが実行される。シーンごとに配置している場合は、プレファブがアクティブなら、シーン開始時にチェックされるようになる。 |
Request When Not Granted | パーミッションをチェックした際、許可されてないときのみ、要求ダイアログを出す(ユーザー設定により、出ないこともある)。オフのときは、要求ダイアログは出さず、結果のみコールバックへ返す。 |
Title, Message, Style, Localize | 権限要求の説明ダイアログのタイトル, メッセージ, スタイル, ローカライズの設定(多言語対応)。 Localize>Localize Resource が設定されてないときは、Title, Message で設定されている文字列のみが使われる(単一言語)。 |
On Result | パーミッションチェックの結果を Permission の文字列と真偽値(true = 許可 / false = 拒否)でコールバックする。複数同時に要求しているとき判別するのに使う。 |
On Granted | パーミッションチェックの結果が「許可(Granted)」のときのみコールバックする。 |
On Denied | パーミッションチェックの結果が「拒否(Denied)」のときのみコールバックする。 |
On Allowed | パーミッションチェックの結果が「許可(Granted)」に変更されたときのみコールバックする(元から許可されてる、または拒否のときは何もしない)。 |
・Manifest.permission(パーミッションの文字列定数)
・テーマ(スタイル)
・【Android】【Java】パーミッションの付与(許可)のチェックと要求をする
■AndroidManifest.xml を設定する
意外と重要なのは、このマニフェストファイルの設定である。少なくとも以前はこの辺りを Unity が自動でやっていてくれたのだが、Unity2017 での Gradle ビルド導入以降、ある程度は自分で書いた方が良いこともある。例えばビルドエラー(or コンフリクト)が出たときなども、手動で直せることもある。
最終的にマニフェストファイルは「Assets/Plugins/Android/AndroidManifest.xml」を中心に統合されたファイルとなる。そして、その設定に従ってアプリが起動する(なのでアプリが起動できないときは、このファイルを疑うのも良い)。
ちなみにデフォルトのマニフェストテンプレートは Unity をインストールしたフォルダ以下の「Editor/Data/PlaybackEngines/AndroidPlayer/Apk/AndroidManifest.xml」にあり、
現在の出力されているマニフェストを見たいなら、ビルドした直後に、プロジェクト内の
「Temp/StagingArea/AndroidManifest.xml」を開けば見ることができる。
・Android マニフェスト
・アプリ マニフェスト
・UnityPlayerActivity Java コードの拡張
ただ、資料を見ると結構難しく感じるので、ここではプラグインに付属している「AndroidManifest_test.xml」(AssetStore版は「_demo.xml」)を複製して「AndroidManifest.xml」にリネームし、これに少し手を加える形で使ってみよう。内容がわかるようになったら、自由に設定すれば良いのである。以前の記事にも書いたが、要点だけを抜き出すと「<manifest>~</manifest>」タグの間に「<uses-permission ~」で要求したい権限を書いておくことが必要となる。

例えば、カメラやマイクの権限を要求したいなら、以下のように書いておく(マニフェストに書いてない権限は要求できない)。
<manifest>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
・・・(略)・・・
</manifest>
・パーミッションの設定
・Manifest.permission(パーミッションの文字列定数)
また、手動で要求する場合、「<application>~</application>」または「<activity>~</activity>」タグの間に、以下を入れて「自動で要求するのをスキップさせる」と良いとも公式に書いてある。
<meta-data android:name="unityplayer.SkipPermissionsDialog" android:value="true" />
・Android マニフェスト
まぁ、この辺りは定形処理なので、そのうちまた自動化されそうだが(もしかしたら、この自動化あたりがバグっている?[Unity2018.3.1f1 時点])、最近は色々なプラグインを導入する機会も増えてきたので、覚えておくとイザというとき役に立つだろう。
(関連記事)
【Android】【Java】パーミッションの付与(許可)のチェックと要求をする
【Unity】Androidのトーストやダイアログ、通知、音声認識、ハード音量操作など基本的な機能を使えるプラグインを作ってみた
【Unity】AssetStore版 FantomPlugin のセットアップ
【Unity】Unity2018 でビルドエラー「CommandInvokationFailure: Gradle build failed.」が出る
【Unity】【C#】モバイルビルド中の警告:Game scripts or other custom code contains OnMouse_ event handlers.~ を消す
【Unity】【C#】テキストファイルの読み書きをする(リソース/ストレージ) 
2018/07/26 Thu [edit]
Unity では内部リソースからテキストファイルを読み込む方法が非常に簡単に用意されているが、それとは別に外部のリソース(ストレージ等)でテキストファイルを読み書きする方法も書いておこう。
またついでに Android でプラグインを利用して読み書きする方法も紹介しておく。ちなみに Unity から C# で直接 SDカードに書き込もうとすると、アクセス拒否で失敗するが、プラグインを利用する場合は、SDカードにも書き込むことが可能だ。エクスプローラみたいなファイル選択も使えるので、ユーザーが自由にファイルの読み書きを行えるようなシステムを作るには役に立つだろう。
ここでは C# スクリプト例はインスタンスメソッドとして書いておくが、static なライブラリとして利用したいなら、例外処理を throw などすれば良いと思う。とりあえず簡単な実装を書いておこう。自由に改造でもして使って欲しい。
■ローカルストレージなどでテキストファイルの読み書きをする(C# スクリプト)
■Android でファイル選択+テキストファイルの読み書きをする(プラグイン利用)
(※) Unity 5.6.3p1 - 2018.1.8f1 / Windows10(x64) で確認
■リソースからテキストアセットを読み込む(Unity ビルトイン機能)
ここでは Unity の機能を使って、アプリに内包したテキストファイルを読み込んでみよう。
これは Unity のエディタ上であらかじめリソースとして持っておき、ランタイム時にロードする方法だ。Unity では「Resources」というフォルダを作っておくと、起動後にリソースとしてテクスチャやデータなどを読み込むことができる。ここにテキストファイルを置いておけば、「TextAsset」として簡単に扱える。それを利用して読み込んでみよう。
●リソースからテキストアセットを読み込む(メソッド定義)
using UnityEngine;
using UnityEngine.UI;
public string textAssetName = "Texts/テスト"; //拡張子はいらない
public Text displayText; //表示するUI-Text
//リソースからテキストアセットを読み込む
void LoadTextAsset(string name)
{
if (string.IsNullOrEmpty(name) || displayText == null)
return;
TextAsset textAsset = (TextAsset)Resources.Load(name, typeof(TextAsset));
if (textAsset != null)
displayText.text = textAsset.text;
else
Debug.Log("Not found TextAsset : " + name);
}
●使用例(メインでのコードなど)
using UnityEngine;
//ロードボタンのコールバックハンドラ
public void OnLoadTextAsset()
{
LoadTextAsset(textAssetName);
}
読み込み先テキストには UI-Text(displayText)を用いているが、もちろん string 型の引数のメソッドを作って直接読み込んでも良い。これはあくまでも例なので、その辺りは用途に応じて書き換えて欲しい。

テストするには UI-Button などを適当に配置し、「Button」の「OnClick()」にスクリプトの「OnLoadTextAsset()」を登録すれば良い。


●「テスト用スクリプトのアタッチ例

●ファイルの内容は任意(UTF-8)

※ランタイム時にログを見るにはプラグインライブラリのプレファブ「DebugConsole」をシーンに置き、コード中の Debug.Log() を XDebug.Log() に置き換えて下さい。また、インスペクタで「displayText」に「DebugConsole」以下の「Text」を登録します。
■ローカルストレージなどでテキストファイルの読み書きをする(C# スクリプト)
次にパス(ファイル名)を指定してテキストファイル(UTF-8)を読み書きすることをやってみよう。
例ではフォルダ(ディレクトリ)に「Application.persistentDataPath」を使っているが、これはプラットフォームによって変わるデフォルトの永続的な保存先となる。また、会社名(company name)やアプリ名(product name)でもフォルダ分けされる。詳しくは公式マニュアルで確認して欲しい。
(参考)Application.persistentDataPath
●ローカルストレージなどでテキストファイルの読み書きをする(メソッド定義)
using System;
using System.IO;
using System.Text;
//テキストをファイルから読み込む(行読み)
//※Android で SD カードから読み込みをするには、「AndroidManifest.xml」にパーミッション("READ_EXTERNAL_STORAGE" または "WRITE_EXTERNAL_STORAGE")が必要。
string LoadText(string path)
{
StringBuilder sb = new StringBuilder(1024); //※capacity は任意
try
{
using (StreamReader reader = new StreamReader(path))
{
while (!reader.EndOfStream)
{
string line = reader.ReadLine();
sb.Append(line).Append("\n");
}
}
}
catch (Exception e)
{
Debug.Log(e.Message);
return null;
}
return sb.ToString();
}
//テキストをファイルに保存
//※Android で External Storage に書き込みをするには、「AndroidManifest.xml」にパーミッション("WRITE_EXTERNAL_STORAGE")が必要。
//※セキュリティ上、Unity から直接 SD カードには保存できない。
bool SaveText(string text, string path)
{
try
{
using (StreamWriter writer = new StreamWriter(path))
{
writer.Write(text);
writer.Flush();
writer.Close();
}
}
catch (Exception e)
{
Debug.Log(e.Message); //Access to the path "filename" is denied. → パーミッションが無い, 書き込みアクセス不可(SDカードなど)
return false;
}
return true;
}
●使用例(メインでのコードなど)
using UnityEngine;
using UnityEngine.UI;
public string filename = "test.txt";
public Text displayText; //表示するUI-Text
//ロードボタンのコールバックハンドラ
public void OnLoadClick()
{
if (string.IsNullOrEmpty(filename) || displayText == null)
return;
string path = Path.Combine(Application.persistentDataPath, filename); //プラットフォームによってパスは異なる
if (!File.Exists(path))
{
Debug.Log("Not found : " + path);
return;
}
string text = LoadText(path);
if (!string.IsNullOrEmpty(text))
displayText.text = text;
}
//セーブボタンのコールバックハンドラ
public void OnSaveClick()
{
if (string.IsNullOrEmpty(filename) || displayText == null)
return;
string path = Path.Combine(Application.persistentDataPath, filename); //プラットフォームによってパスは異なる
if (SaveText(displayText.text, path))
Debug.Log("Save to : " + path);
}
テストするには UI-Button などを適当に配置し、「Button」の「OnClick()」にスクリプトの「OnLoadClick()」「OnSaveClick()」をそれぞれ登録すれば良い。
![]() | ![]() |
![]() | ![]() |
読み書きするテキストには UI-Text(displayText)を用いているが、もちろん string 型の引数のメソッドを作って直接読み書きしても良い。これはあくまでも例なので、その辺りは用途に応じて書き換えて欲しい。
なお、Android でSDカードに読み書きする場合は以下のパーミッションが必要になる。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />'
パーミッションについての説明が必要なら以前の記事を参照して欲しい。

※ランタイム時にログを見るにはプラグインライブラリのプレファブ「DebugConsole」をシーンに置き、コード中の Debug.Log() を XDebug.Log() に置き換えて下さい。また、インスペクタで「displayText」に「DebugConsole」以下の「Text」を登録します。
■Android でファイル選択+テキストファイルの読み書きをする(プラグイン利用)
ついでにプラグインに入っている「StorageLoadTextController」と「StorageSaveTextController」(~/FantomLib/Prefabs/System/ 以下。検索で探すと簡単)というテキストファイル読み書きの機能を使ってみよう。これら「~Controller」は Android 標準のファイル選択機能を使い、テキストファイルを読み込み・書き込みをしてくれるものだ。これら機能はプラグイン内部に実装されているので、自分でコードを書く部分は、機能呼び出しと結果受け取りだけで良い。
ではまず、その機能呼び出しと結果受け取りのコードだけ書いてしまおう。名前は任意で良い。これらは各「~Controller」や UI-Button のコールバックハンドラとなる。
●コールバックハンドラ例(メインでのコードなど)
using UnityEngine;
using UnityEngine.UI;
using FantomLib;
public Text displayText; //表示するUI-Text
//読み込んだテキストを UI-Text に表示する
public void OnStorageLoad(string text)
{
if (string.IsNullOrEmpty(text) || displayText == null)
return;
displayText.text = text;
}
public StorageSaveTextController storageSaveTextController; //※インスペクタで登録
//UI-Text のテキストをファイルに保存する
public void OnStorageSave()
{
if (displayText == null || string.IsNullOrEmpty(displayText.text)) //※空は保存しない場合
return;
if (storageSaveTextController != null)
storageSaveTextController.Show(displayText.text);
}
//エラーステータス用コールバックハンドラ
public void OnError(string message)
{
Debug.Log(message);
}
あとはヒエラルキーに「StorageLoadTextController」と「StorageSaveTextController」(~/FantomLib/Prefabs/System/ 以下。検索で探すと簡単)を置き、UI-Button など(※名前は任意)を Canvas に配置したら、インスペクタでコールバックを設定するだけだ。
![]() | ![]() |
![]() | ![]() |
![]() | ![]() |
あとはビルドするだけだが、プラグインを含む場合のビルドは「AndroidManifest.xml」が必要になる。その辺りは以前の記事にまとめてあるので参照して欲しい。もちろん「Build Settings...」にシーンを追加するのを忘れずに。

※ランタイム時にログを見るにはプラグインライブラリのプレファブ「DebugConsole」をシーンに置き、コード中の Debug.Log() を XDebug.Log() に置き換えて下さい。また、インスペクタで「displayText」に「DebugConsole」以下の「Text」を登録します。
※とりあえず試してみたい方は、最新版をビルドした apk デモをダウンロードできます。動作確認にもどうぞ。


Android 4.2以上
※「提供元不明アプリのインストール」許可が必要です。
(関連記事)
【Unity】AssetStore版 FantomPlugin のセットアップ
【Unity】Androidのトーストやダイアログ、通知、音声認識、ハード音量操作など基本的な機能を使えるプラグインを作ってみた
【Unity】【C#】UnityEvent, Action, delegate, interface でのコールバック実装方法とインスペクタでの登録
【Unity】【C#】動的にオーディオファイルの読み込みと再生をする 
2018/07/04 Wed [edit]
プラグイン ver.1.16 の簡易音楽プレイヤーを作る際にちょっと調べたんだけど、VideoPlayer と違って、基本的に WWW を使うのが常套みたいだね。プラグインのデモスクリプトとしては「EasyMusicPlayer.cs」と「ExternalStorageTest2.cs」の2種類で書かれているが、基本は同じなので再利用しやすい部分を抜粋して書いておくことにした。実際に使う際にはもう少し手を加えた方が便利かも知れない。
|
(※) Unity 5.6.3p1 - 2018.1.8f1 / Windows10(x64) / Galaxy S7 Edge (Android 7.0) で確認
■オーディオファイルの読み込みと再生のコード
●オーディオファイルの読み込みと再生
using System.Collections;
using System.IO;
using UnityEngine;
public class AudioLoadTest : MonoBehaviour //※クラス名は任意
{
public AudioSource audioSource; //インスペクタで AudioSource をセット
public string path = "/storage/emulated/0/Music/sample.mp3"; //※ファイルは任意
//外部からの呼び出し用メソッド
public void LoadAudio(string path)
{
if (Path.GetExtension(path) == ".m4a") //※"m4a"は再生できないっぽい
{
Debug.Log("Not supported audio format.");
return;
}
StartCoroutine(LoadToAudioClipAndPlay(path));
}
//ファイルの読み込み(ダウンロード)と再生
IEnumerator LoadToAudioClipAndPlay(string path)
{
if (audioSource == null || string.IsNullOrEmpty(path))
yield break;
if (!File.Exists(path)) {
//ここにファイルが見つからない処理
Debug.Log("File not found.");
yield break;
}
using(WWW www = new WWW("file://" + path)) //※あくまでローカルファイルとする
{
while (!www.isDone)
yield return null;
AudioClip audioClip = www.GetAudioClip(false, true);
if (audioClip.loadState != AudioDataLoadState.Loaded)
{
//ここにロード失敗処理
Debug.Log("Failed to load AudioClip.");
yield break;
}
//ここにロード成功処理
audioSource.clip = audioClip;
audioSource.Play();
Debug.Log("Load success : " + path);
}
}
// Use this for initialization
private void Start () {
//起動時に読み込むときなど
LoadAudio(path); //※メインからの呼び出し例
}
}
ここではインスペクタに path を入力し読み込むようになっているが、外部呼び出し用のメソッド「LoadAudio()」の引数にパスを渡すようになっているので、通常は「Start()」内の呼び出しは削除した方が良いだろう(ただのメインからの呼び出し例のため)。
オーディオファイルの読み込みには WWW を使っているが、あくまでローカルストレージを想定しているので、頭に "file://" を付けているのに注意して欲しい。インターネットからダウンロードしたい場合は "file://" を取り除いて URL形式("http://~")を直接与えれば良いと思う。しかしその場合、タイムアウトを付けたり、キャッシュ付きなどを使う必要があるかも知れない(パケ代もかかるので)。
WWW を使っている分にはオーディオ形式は気にしなくても良いが、再生するには "mp3" や "ogg", "wav" などが良いようだ。"m4a" は読み込み(ダウンロード)はできるが、再生はできなかった(Unity2018.1.5f1時点。Windows はエディタのみ。ランタイムは以下を参照)。
・Windows で mp3 をランタイムで再生する
スマホで使うにはアクセス権などが必要になることもあるが、とりあえずはこれだけで読み込みと再生はできる。以降では更にプラグインを利用して、自由にファイルを選択して読み込む方法もやってみよう。
・Android アプリでパーミッション(権限)要求をする
■スマホ(Android)のストレージから読み込んで再生する
ここではプラグインを使ってストレージを開き、再生する方法を書いておこう。といってもスクリプト自体は上記の例そのままで良いので、後はプレファブをシーンに置き、コールバックをセットするだけだ。プラグインのインストールからはじめる場合は、以前の記事を参考にして欲しい。
1.先に作った「AudioLoadTest.cs」スクリプトを適当な GameObjectにアタッチし、「AudioSource」を追加し、インスペクタでセットドラッグ&ドロップでセットしよう。「Play On Awake」はオフに、「Loop」はオンにしておくと良い(※曲を繰り返し再生する場合)。

2.シーンにプレファブ「StorageOpenAudioController」(~/FantomLib/Prefabs/System/ 以下。検索で探すと楽)を置き、インスペクタで「Mime Types」に読み込むオーディオ形式の MIME type を入れておく。ここでは mp3/m4a = "audio/mpeg", ogg = "audio/ogg","application/ogg" を入れているが、任意で良い(※デフォルト=空の状態ではすべてのオーディオ形式となる)。


なお、ogg の MIME type が2種類書かれているが、プロバイダ(ストレージ)の種類によって、同じ拡張子でも MIME type が違ってたりするので注意が必要だ。例えばローカルストレージでは "application/ogg" となり、GoogleDrive などでは "audio/ogg" で認識される。今回の再生の場合、ローカルストレージの "application/ogg" だけでも良い(複数指定して置けば、どのプロバイダ[ストレージ]でも見えるようになる)。直接開けるか否かはアプリの対応状況によるため、実際に使う際にはあらかじめ絞り込んでおくのも良いだろう。
※ここで言う「プロバイダ」とはアプリが持つ情報提供プログラムのことである。Android アプリはそれぞれアプリごとにプロバイダを持つことができ、それによりユーザーに与える情報を制限することができる。この例の場合、ローカルストレージや GoogleDrive(これは1つのアプリである)、OneDrive(これもアプリ)ごとということになるので、「ストレージ」ごとになることと同義になる。
3.シーンにロード用のボタンを置き、コールバック「OnClick」に「StorageOpenAudioController.Show」を登録する。これでボタンを押すことにより、ストレージが開く。


4.プレファブ「StorageOpenAudioController」に戻り、「OnResult」に先に作ったスクリプト「AudioLoadTest.LoadAudio」を登録する(※手順2の画像のようになる)。これでストレージから選択したオーディオファイルのパスがスクリプトに渡され、読み込みが成功すれば再生される(※"m4a" は再生できないようなので(Unity2018.1.5f1 時点)、LoadAudio() で拡張子チェックをしてるが、実際に使うには拡張子で絞るようにしても良い。「EasyMusicPlayer.cs」(~/FantomLib/Scripts/Example/ 以下)にはその例も書かれているので必要なら参照)。なお、GoogleDrive などクラウドストレージからは直接再生(情報取得)できないので注意。その場合は一旦ローカルストレージにコピー(ダウンロード)すれば再生できるようになる。これで読み込みと再生だけなら完成だ。

※実機でログを確認するにはシーンに「DebugConsole」(~/FantomLib/Prefabs/System/ 以下)を置き、「AudioLoadTest.cs」内の「Debug.Log()」→「XDebug.Log()」にしておく。ビルドするには「デモのビルド」と基本的に同じ(シーンだけ変える)なので必要なら参照。
あとは「プレイ/停止」など操作できるとなお良いね。このあたりのサンプルはデモシーン「ExternalStorageTest」の「ExternalStorageTest2.cs」に、またはシーン「MusicPlayerExample」の「EasyMusicPlayer.cs」(~/FantomLib/Scripts/Example/ 以下)に書かれているので、コピペしても良いと思う。「EasyMusicPlayer.cs」には連続再生やシャッフル、次の曲/前の曲、プレイリストに追加/削除など、一般的な操作の例を入れてあるので、必要なら参照して欲しい(最低限の機能で良いなら、そのまま使っても良い→「UnityChanInOtakuCity」はそのまま使ってる)。
|
※とりあえず試してみたい方は、最新版をビルドした apk デモをダウンロードできます。動作確認にもどうぞ。


Android 4.2以上
※「提供元不明アプリのインストール」許可が必要です。
(関連記事)
【Unity】【C#】Windows で mp3 をランタイムで再生する
【Unity】【C#】オーディオ再生でのエラー:An invalid seek position was passed to this function の対処法
【Unity】AssetStore版 FantomPlugin のセットアップ
【Unity】Androidのトーストやダイアログ、通知、音声認識、ハード音量操作など基本的な機能を使えるプラグインを作ってみた
【Unity】【C#】VideoPlayer で動画の終了判定をする

【Unity】スマホで簡易360度(パノラマ, 全天球)ビューワを作る 
2018/05/29 Tue [edit]
タイトルは "スマホ"(※Android)となっているが、実際には他のプラットフォームでも関係ないので、作り方を覚えおけば色々応用が効くだろう。特に全天球への画像(動画)貼り付けは VR に使えばそのまま背景にできるので、Cardboard VR や GearVR、Oculus Go などにも簡単に流用できる(というより、元々「VRコンテンツ開発ガイド 2017」を以前読んでいたので、それをスマホに応用した)。ミクシータ(RICHO THETA) など360度カメラを持っている人は、保存した画像をそのまま使えるので試してみると良い(持ってなくても Google Play のアプリのサンプルでスマホに画像を保存すれば確認できる)。ARに応用してる例もあるね。
|
なお、今回の記事はプラグインのギャラリー読み込みデモ(GalleryPickTest)のセットアップも兼ねている。サンプルシーンを使えば1から構築する必要はないので、すぐに試してみたい人はプラグインをダウンロードして欲しい。AssetStore版(ver.1.15以降[無料])とGoogleDrive版の2つがあるが、基本的にはどちらも同じものだ。好きな方で構わない。
※とりあえず試してみたい方は、最新版をビルドした apk デモをダウンロードできます。動作確認にもどうぞ。


Android 4.2以上
※「提供元不明アプリのインストール」許可が必要です。
プラグイン自体のセットアップは以前の記事を参照して欲しい(>>GoogleDrive版 | >>AssetStore版)。デモが入っているパスは GoogleDrive 版では「Assets/_Test/」に、AssetStore版は「Assets/FantomPlugin/Demo/」となっているので適宜置き換えて欲しい。ファイル名は基本的に同じだ。
■プラグインのセットアップ(AssetStore 版) [※別ページ]
■全天球素材のダウンロードと設定(360度ビューワ)
■更新履歴
(※) Unity 2018.1.0f2 / Windows10(x64) / Galaxy S7 Edge (Android 7.0) で確認
■全天球素材のダウンロードと設定(360度ビューワ)
360度のビューワを作る際には法線が内側を向いている球状メッシュを使う必要がある(Unityのデフォルトの球状メッシュは外側向き)。要するに球の内側から覗いたとき映像が見える必要があるので、通常は3Dモデリングツールなどで素材を作らなくてはならない。しかし幸いにも素材を提供してくれている方がいるので、有り難く使わせて頂こう(素材を提供してくれる人は神ですね(笑))。以下のページにある「Sphere100.fbx」(※ページ内で検索するとすぐ見つかる)をダウンロードして欲しい。
・UnityとOculusで360度パノラマ全天周動画を見る方法【無料編】 で「Sphere100.fbx」をダウンロード(※直接ダウンロードが簡単)。

ダウンロードが完了したら、プラグインのサンプルシーンを使って実際にセットアップしてみよう。プラグインを利用している箇所はスマホから画像や動画のパスを取得しているだけなので、あらかじめプロジェクトに素材を含んでいる分にはプラグイン機能を使う必要はない。画像や動画を動的に貼り付ける部分は Unity の機能なので、コピペして色々なアプリに応用すれば良いだろう(「GalleryPickTest2.cs」にまとめてある)。それでは以下の方法で、サクッと簡単に360度のビューワを作ってみよう(笑)。
1.ダウンロードした「Sphere100.fbx」を Unity のプロジェクトにドラッグ&ドロップしよう(任意のフォルダで良い)。またインポートした「Sphere100」をクリックして、インスペクタで「Model>Scale Factor」を「1000」にしておく(大きさは任意でも良い)。


2.次にギャラリーから画像を取得するデモシーン「GalleryPickTest」(GoogleDrive版は「Assets/_Test/Scenes/」, AssetStore版は「Assets/FantomPlugin/Demo/Scenes/」内にある。検索を使うと簡単)を開こう。このデモはスマホの標準ギャラリーアプリを開き、画像や動画のパスを取得して Unity に取り込むものだが、オプション(形状)の「360 degrees」にはダミーのテキスト「Please replace with 'Sphere100', and set 'TextureMat' as material.」が表示されるのみで何も表示されない(プレイして「360 degrees」を押してみるとテキストが表示される)。このダミーテキストを全天球メッシュに置き換えることで、簡易360度ビューワにすることができる。

3.ヒエラルキーから「Stage」を開こう。この中にある「Sphere100 (360degrees Dummy)」(画像用)と「Sphere100Video (360degrees Dummy)」(動画用)が全天球ダミーなわけだが、この階層にインポートした「Sphere100」をドラッグ&ドロップしてオブジェクトを配置しよう。「Sphere100 Video」となってる方は「Sphere100」を複製(Ctrl-D)して名前を変えただけのものである。

4.各オブジェクトの Position が (0, 0, 0) となっているのを確認したら、次に Scale を変更しておこう。大きさは任意で良いが、ポイントは X軸を負の値にしておくことだ。これは正の値で試して見ればわかると思うが、カメラは球の内側から覗く感じになるので、正の値だと画像が左右反転して見える。なので、負の値にしておけば人の目には正しい方向に見えるというわけだ。またついでにオブジェクトに影を付ける処理は必要無いので、すべてオフにしておくのも良い(このデモでは影の無いマテリアルを使うので必須ではないが[※後述↓手順5])。

●動画用全天球「Sphere100 Video」

※マテリアルのセットは下記(↓手順5)
5.あとは全天球に画像を映し出すためにマテリアルをセットしよう。GoogleDrive版では「Assets/_Test/Metarials/」に、AssetStore版は「Assets/FantomPlugin/Demo/Metarials/」に画像用の「TextureMat」、動画用の「VideoRenderTextureMat」があると思うので(プラグイン ver1.15以降)、それらをそれぞれ「Sphere100」「Sphere100 Video」の「Materials」にセットして欲しい。上記(↑手順4)のインスペクタのような感じになる。

ちなみにこの「TextureMat」と「VideoRenderTextureMat」は特別なものではなく、「TextureMat」はプロジェクトビューで右クリックして「Create>Material」で新規マテリアルを作成し、インスペクタで「Shader」を「Unlit>Transparent」にしただけのもので、「VideoRenderTextureMat」の方は、先に「Create>Render Texture」を作っておき、同じように新規マテリアル(Create>Material)で「Shader」を「Unlit>Texture」にして、テクスチャに作っておいた「Render Texture」をセットしただけのものだ。ほぼデフォルトのままなので、必要あれば調整などは適当にやって欲しい(※ただし、このデモでは GalleryPickTest2.fitRenderTexture = true のとき、Render Texture を動画サイズに合わせて動的に生成するので、実際には使ってない。fitRenderTexture = false にするとセットした「VideoRenderTexture」を使うようになる[※解像度が固定サイズで良いときなどに使うと、負荷が少し軽くなる])。
6.最後にデモスクリプトの「GalleryPickTest2」をヒエラルキーで選択して、「Sphere」と「Video Sphere」にそれぞれ「Sphere100」「Sphere100 Video」のオブジェクトをセットしよう(初期状態では「Dummy」がセットされている)。これで準備は完了だ。


エディター上でプレイして「360 degrees」をクリックしたら、背景が真っ白になったら成功だ(画像が読み込まれてないので白いだけ)。ビルドして実機で確認する方法はこちらの記事を参照して欲しい。
・デモのビルド
![]() | ![]() |
通常の画像を読み込んでも良いが、天井と底面の方を見ると収束してるので、せっかくなので全天球画像を読み込んでみよう。なんとあの日本列島360の全天球静止画がBOOTHにて無料で配布されている(まさに神!)。これをダウンロードしてスマホのストレージにコピーしよう。ギャラリーから読み込むと超美麗な360度画像を楽しむことができる(利用方法は規約に従ってね)。
|
また以下のミクシータのアプリをインストして、保存したサンプルの画像を読み込んでみるのも良い。VR空間で見ると、まるでその場所にいるようで更に面白い。GearVR はそのままホーム>ギャラリーで観れるが、Cardboard なら色々ビューワアプリが出てるので観てみると良いだろう。ちなみに Unity 使える人なら、Cardboard VR も GearVR も作るのはそう難しくはない(むしろVR内操作 UI 作る方が難しいね(笑))。しかし、全天球メッシュにあらかじめ画像を貼り付けておけば簡単に360度にできるので、挑戦してみるのも良いだろう。
・RICOH THETA Type HATSUNE MIKU (Google Play) ※カメラが無くても、サンプル画像が入っているので、保存すれば360度画像を試せる。
・VU Gallery VR 360 Photo Viewer (Google Play) ※Cardboard の360度ビューワアプリ
・【Unity】GearVR アプリをビルドする
|
|
(関連記事)
【Unity】AssetStore版 FantomPlugin のセットアップ
【Unity】Androidのトーストやダイアログ、通知、音声認識、ハード音量操作など基本的な機能を使えるプラグインを作ってみた
【Unity】GearVR アプリをビルドする
【Unity】ARCore を使って現実世界にプロ生ちゃんを召喚してみる

- 関連記事
-
-
【Unity】【C#】クエリちゃんを飛行させる!
-
【Unity】InputSystem 対応 ダブル/トリプル(n回)クリック操作ライブラリ (FantomPlugin 追加機能)
-
【Unity】【Android】マルチウィンドウを禁止する
-
【Unity】【エディタ拡張】Game View の解像度を取得する
-
【Unity】スマホで簡易360度(パノラマ, 全天球)ビューワを作る
-
category: Unity
thread: ゲーム開発
janre: コンピュータ
tag: Unityライブラリ Unityプラグイン FantomPlugin VR