【Unity】Androidでカスタマイズしたダイアログを動的生成できるプラグインを作ってみた [⇒PCページへ]

2017年12月03日22:57  Unity 写真あり


 これまで、スイッチスライダーといったUIを並べるダイアログを作ってみたが、その他にトグルボタン(Android ではラジオボタン:RadioButton)を加え、テキストや分割線を自由に入れられるようにすることにより、大まかな設定変更などに利用できるようにカスタマイズ可能なダイアログを作ってみた。

 今回はこれまでの集大成とも言えるので元の Java コードは割愛して、Unity での利用方法を中心に解説しようと思う。自分で作りたい場合は、過去の記事に簡略したものだがソースコードも載せてあるので、それらをすべて集めたものと考えても良いだろう。

 また、コードで書くのは少し難しいので、専用のプレファブ(CustomDialogController)で簡単に生成する方法も別記事に掲載してある。あまり凝ったものでなければ、そちらを使った方が楽だろう。

【Unity】カスタムダイアログを簡単に生成するプレファブを作ってみた(CustomDialogController)

 今回も Androidの基本機能を利用するプラグインのアップデート版となる。追加内容・仕様変更などはなるべく更新履歴に書くようにしているが、基本的にはそのまま使えるようにしているので、旧バージョンがある場合は上書きでも構わないと思う。プラグイン自体のセットアップは以前の記事を参照して欲しい。

>>プラグイン&サンプルをダウンロード
(Google Drive を利用。画面右上にあるダウンロードアイコンを押す)


 パッケージに同梱されているサンプルでは、シーン「Assets/_Test/Scenes/DialogExTest」で使っているので、適当に複製などして自由にカスタマイズして欲しい。

■プラグインのセットアップ
■各UIの生成とプロパティ解説
 ●分割線を生成する
 ●テキストを生成する
 ●スイッチを生成する
 ●スライダーを生成する
 ●トグルボタン(グループ)を生成する
■カスタムダイアログを表示する
■カスタムダイアログの戻り値を取得する
 ●キーと値のペア("key=value")からパラメタを取得する
 ●JSON形式("{"key1":"value1"}")からパラメタを取得する
■更新履歴

(※) Unity 5.6.3p1 / AndroidStudio 2.3.3 / Windows10(x64) / Galaxy S7 Edge (Android 7.0) で確認



■各UI(アイテム)の生成とプロパティ解説

 はじめに大まかな解説をしておくと、各UI(以下、アイテムとも呼ぶ)はそれぞれのインスタンスを生成して、プラグイン用の独自のアイテムクラス(DialogItem)の配列として、カスタムダイアログ生成のメソッド(ShowCustomDialog())に渡すことで生成される。生成順(配置順)は配列の先頭から順に、ダイアログの上から縦方向に並べられることになる。各インスタンスはUIごとに引数が異なるのでそれぞれの解説を見て欲しいが、それらは全て DialogItem クラスを継承しているので、1つの配列に代入できる。

using FantomLib;

//すべてのアイテムは DialogItem を継承しているため代入できる
DialogItem[] dialogItems = new DialogItem[]
{
new DivisorItem(lineHeight),
new TextItem(text),
new SwitchItem(text, key, defChecked),
new SliderItem(text, key, value),
new ToggleItem(items[], key, values[], defValue),
};

 テキストや分割線は値を持たないが、スイッチ、スライダー、トグルボタン(グループ)は値を持ち、それぞれのアイテムにキーを設定することにより "key1=value1\nkey2=value2" のようなキーと値のペアが改行区切り("\n")で文字列となって、戻り値として Unityへコールバックメソッドで返される。または JSON形式(resultIsJson=true)にすることにより "{"key1":"value1","key2":"value2"}" で返すことも可能だ。Android → Unity へは1つづきの文字列として返されるので、受け取った値は適宜分割・変換して使うことになる。ライブラリとして簡単に分割・型変換するクラスも入れておいたので、それらは後述の「カスタムダイアログの戻り値を取得する」を見て欲しい。

 実際のコードは「Assets/_Test/Scripts/CastomDialogTest.cs」にまとまっているので、適当にコピペなどして引数を書き換えれば、すぐに利用できるだろう。

 以下ではそれぞれのアイテム(UI)の生成方法(インスタンス)と簡単な引数の解説をを書いておこう。



●分割線を生成する
using FantomLib;

DivisorItem divisor = new DivisorItem(lineHeight, lineColor);

●引数
lineHeight線の太さ。単位は Android の dp となる。
lineColor線の色。色形式は ARGB の int値 または Unity.Color(オーバーロード)。0 を与えると指定なし(デフォルト=灰色)となる。省略可(=0)。





●テキストを生成する
using FantomLib;

TextItem text = new TextItem(text, textColor, backgroundColor, align);

●引数
text表示するテキスト文字列。
textColorテキストの色。色形式は ARGB の int値 または Unity.Color(オーバーロード)。0 を与えると指定なし(デフォルト=薄い黒)となる。省略可(=0)。
backgroundColorテキストの背景色。色形式は ARGB の int値 または Unity.Color(オーバーロード)。0 を与えると指定なし(デフォルト=なし[システムによる])となる。省略可(=0)。
align文字揃え。"center" で中央寄せ、"right" で右寄せ、"left" で左寄せとなる。空文字("") を与えると指定なし(デフォルト=左寄せ[システムによる])。省略可(="")。





●スイッチを生成する
using FantomLib;

SwitchItem sw = new SwitchItem(text, key, defChecked, textColor);

●引数
text表示するテキスト文字列。
keyコールバックの戻り値で値に紐付けするキー。"key=value" または "{"key":"value"}" のような形式で返される。
defCheckedスイッチの初期値。true = オン, false = オフ
textColorテキストの色。色形式は ARGB の int値 または Unity.Color(オーバーロード)。0 を与えると指定なし(デフォルト=薄い黒)となる。省略可(=0)。





●スライダーを生成する
using FantomLib;

SliderItem slider = new SliderItem(text, key, value, min, max, digit, textColor, changeCallbackMethod);

●引数
text表示するテキスト文字列。
keyコールバックの戻り値で値に紐付けするキー。"key=value" または "{"key":"value"}" のような形式で返される。
value初期値 (整数部分6桁+小数点以下3桁まで)
min取り得る最小値。省略時は 0 (整数部分6桁+小数点以下3桁まで)
max取り得る最大値。省略時は 100 (整数部分6桁+小数点以下3桁まで)
digit小数点以下(0:整数, 1~3:小数点以下桁数)。省略時は 0(整数)。
textColorテキストの色。色形式は ARGB の int値 または Unity.Color(オーバーロード)。0 を与えると指定なし(デフォルト=薄い黒)となる。省略可(=0)。
changeCallbackMethodリアルタイムにスライダーで値を変化させたときのコールバックメソッド名(GameObject 名は ShowCustomDialog() の引数になる)。「OK」のときの結果とは別に送信される(戻り値は "key=value" のみ)。省略可(="")。





●トグルボタン(グループ)を生成する
using FantomLib;

ToggleItem toggle = new ToggleItem(items[], key, values[], defValue, textColor);

●引数
items[]選択肢の文字列の配列。
keyコールバックの戻り値で値に紐付けするキー。"key=value" または "{"key":"value"}" のような形式で返される。
values[]各選択肢に対する値(文字列)。戻り値になる。
defValue
 または
checkedItem
初期値の文字列 または インデクス(オーバーロード)。defValue の方が優先で、空文字("") または選択肢に存在しない defValue の場合はインデクスが適用される。
textColorテキストの色。色形式は ARGB の int値 または Unity.Color(オーバーロード)。0 を与えると指定なし(デフォルト=薄い黒)となる。省略可(=0)。





■カスタムダイアログを表示する


 前述のアイテム(UI)の生成をしたら、あとはそれらを DialogItem[] の配列に代入して ShowCustomDialog() を呼び出すだけだ。引数もこれまでとあまり変わらないが、ここではいくつか重要なものだけをピックアップして書いておこう。

●カスタムダイアログを表示するコード
using FantomLib;

#if UNITY_ANDROID && !UNITY_EDITOR
AndroidPlugin.ShowCustomDialog(title, message, dialogItems[], callbackGameObject, callbackMethod,
resultIsJson, okCaption, cancelCaption, style);
#endif

●引数(いくつか割愛)
messageタイトルの下に少し小さく表示されるテキスト。注意点はダイアログに収まらないほどのアイテム(UI)を追加したときには表示されないということだ(Android ダイアログの仕様(?)。ボタンも表示領域から追い出されることがある)。その場合は非表示(空文字(""))にすれば良い。
dialogItems[]ダイアログに配置するアイテム(UI)の配列。各アイテムのインスタンスの生成方法は「各UIの生成とプロパティ」を参照。
callbackGameObject結果をコールバックするヒエラルキーにある GameObject 名。スライダー値の変化をリアルタイムに取得するコールバックもこの GameObject となる
callbackMethod結果をコールバックする callbackGameObject にあるメソッド名。ただし「OK」ボタンを押したときのみで「キャンセル」時やダイアログ外をタッチしてダイアログを消したときはコールバックされない
resultIsJson「OK」ボタンを押したときの結果コールバック(callbackMethod)に返されるパラメタを JSON形式にするかどうかのフラグ。デフォルトは false で "key1=value1\nkey2=value2" のようなキーと値のペアで1つづきの文字列として送られる。true にすると "{"key1":"value1","key2":"value2"}" のような JSON形式になる。JSONは Unity の JsonUtility でパースすることもできる。キーと値のペア("key=value")を簡単に扱うクラスもライブラリとして追加しておいたので、後述を参照
styleダイアログに適用できるテーマ(スタイル)。省略=空文字("")のときはアクティビティのテーマと同じものになる。引数の文字列は "android:Theme.DeviceDefault.Dialog.Alert" のように、名前のアンダバー("_")をドット(".")に変えたものを指定する。端末の API Level によって使えるものとそうでないものがあるので、アプリのビルドの API Level に合わせて指定する必要があるので注意。

(参考)R.style.theme



■カスタムダイアログの戻り値を取得する

 ここではいくつか結果の戻り値をパラメタごとに取得するコードを書いておこう。ShowCustomDialog() の引数の resultIsJson によってキーと値のペア("key=value")と JSON形式("{"key1":"value1"}")が指定できるので、大まかに2種類の方法を書いておく。実際に使ってみるとそれぞれメリット・デメリットはあり、どちらが良いとも言えないので、自分の利用しやすい方を使うと良いだろう。

●キーと値のペア("key1=value1\nkey2=value2")からパラメタを取得する
Dictionary<string, string> dic = new Dictionary<string, string>();  //キーと値の配列などでも良い
string[] arr = result.Split('\n'); //result を結果の文字列とする
for (int i = 0; i < arr.Length; i++)
{
string[] param = arr[i].Split('='); //※キーがあること前提
dic[param[0]] = param[1];
}

//※ System.Linq を使うなら以下でも同じ(※重複キーがあるとエラーになるので注意)
var dic = result.Split('\n').Select(e => e.Split(new char[]{'='}, 2)).ToDictionary(a => a[0], a => a[1]);

 値は全て文字列になるので、必要あれば型変換して使う。デメリットは複数の型を扱うには少し不便なことだろう。メリットは後からパラメタの追加をしやすい所などがある。なので少しばかり楽をするために、パースや型変換するクラス(Param)をライブラリとして追加しておいた。以下にその使い方も書いておこう。

using FantomLib;

//結果のパース
Param param = Param.Parse(result); //result を結果の文字列とする

//型変換して値を取得
string s = param.GetString(key); //または param[key] でも同じ。 string 型で取得
int i = param.GetInt(key); //int 型で取得
float f = param.GetFloat(key); //float 型で取得
bool b = param.GetBool(key); //bool 型で取得

 Param クラスは辞書:Dictionary<string, string> を継承してパースや型変換を付け足しただけのクラスなので、使い方は辞書と同じになる。ただし値の型は文字列に固定されているので、その型変換用に GetXXX()(XXX:は型を表す)が用意されているというわけだ。中身はまんま辞書なので、ライブラリ内に入っている XPlayerPrefs.SetDictionary(), GetDictionary()PlayerPrefs にそのまま保存することも可能だ。それらも簡略化するために、static なメソッドとして Param.SetPlayerPrefs(), Param.GetPlayerPrefs() を追加してある。また、読み込むときなどは GetXXX() にはデフォルト値も引数に渡せるので、保存された値が存在しなかったときも値を設定できるようにしてある。わりと汎用的に使えると思うので、特にこのライブラリ専用というわけでなく、他の用途に使うのも良いだろう。

●JSON("{"key1":"value1","key2":"value2"}")からパラメタを取得する
//受信用のクラスや構造体などを用意する
[Serializable]
class Data { //クラス名は任意
public string s;
public int i;
public float f;
public bool b;
}

Data data = JsonUtility.FromJson<Data>(result); //result を結果の文字列とする

 JSON 形式で結果を受け取りたいときは専用のクラスや構造体を作成して、Unity の JsonUtility を使うことで値を取得することができる。デメリットはこの受信用クラスが必要という所か。パラメタを後から追加する場合もメンバを用意する必要がある。しかしメリットは型変換のコードは必要ないので扱いやすい所だろう。以前にライブラリとして追加した XPlayerPrefs.SetObject(), GetObject() を使えばそのまま PlayerPrefs で保存もできる。データがひとまとめにクラスや構造体になっているのなら、かなり楽に使えるだろう。


 以上の機能はパッケージに同梱されているサンプル「Assets/_Test/Scripts/CustomDialogTest.cs」にまとまっているので、適当に複製などして使えば難しくはないと思う。



■更新履歴

 今回のアップデートを簡単に説明しておくと以下のようになる。[⇒全体の更新履歴はこちら]

カスタムダイアログを追加。
キー&値ペアのテキストのパースと型変換を行う辞書ラッパークラス「Paramをライブラリとして追加。
ハードウェアキーでの音量操作可否のメソッド(AndroidPlugin.SetVolumeOperation())を追加。

※以前のバージョン上書きでも問題なく動作すると思います。


※この記事のUnityアセットはプラグインとして配布されています。


※とりあえず試してみたい方は、最新版をビルドした apk デモをダウンロードできます。動作確認にもどうぞ。

プラグインデモをダウンロード
(Google Drive を利用)


Android 4.2以上
※「提供元不明アプリのインストール」許可が必要です。


(関連記事)
【Unity】カスタムダイアログを簡単に生成するプレファブを作ってみた(CustomDialogController)
【Unity】Androidのトーストやダイアログ、通知、音声認識、ハード音量操作など基本的な機能を使えるプラグインを作ってみた
【Unity】Androidでスライダーで設定を変更するダイアログを使う
【Unity】Androidでスイッチで設定を変更するダイアログを使う
【Unity】Androidの選択ダイアログを使う
【Unity】Androidで日付・時刻選択ダイアログ(DatePicker, TimePicker)を使う
【Unity】Androidで数値・半角英数・パスワード入力ダイアログを使う
【Unity】Androidでテキスト入力ダイアログを使う
【Unity】Androidのテキスト読み上げ(TextToSpeech)を使う
【Unity】Androidのハードウェア音量操作・ハードウェアキーの無効化をする
【Android】【Java】AlertDialog を使ってみる


関連記事
トラックバックURL

http://fantom1x.blog130.fc2.com/tb.php/282-602198c4

前の記事 次の記事