HoloLensで始めるMRDesignLabs - Fitbox、Progress、HelpText、Dialog

#その他のコントロールも何かと便利です。
今回は、FitBox,Progess,HelpText,Dialogについて設定などの紹介をしたいと思います。
あと便利なものにDebug系のものがあるので、こちらは次回に紹介したいと思います。
見た目に影響を与えるボタンや配置に関するコントロールはUI作るうえでかなり大事な要素になります。自前で用意するとなかなか統一感のあるものを作り出すということが難しいと思います。その点でMRDesignLabsは便利ですね。

## 開発環境
* Windows 10 Pro
* Unity 5.6.1f1

## 各種部品の説明
### FitBox
起動時にアプリケーションのタイトルをパネルで表示し、パネルがタップされたらアプリケーションを開始するといったときに使うものです。下のものは元素記号のものですが動画のように最初にパネルを表示、タップで元素記号を表示といった形で利用することができます。ちなみに最新のではパネルのデザインが変わっています。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">要所要所にちゃんと「Fluent Design System」が入ってる。かなり直感的にわかるレベルだけど自然というところがいいですね。何より元素記号が素敵。<a href="https://t.co/000gd8fhLc">https://t.co/000gd8fhLc</a> <a href="https://t.co/75Bnveo3sU">pic.twitter.com/75Bnveo3sU</a></p>&mdash; takabrz (@takabrz1) <a href="https://twitter.com/takabrz1/status/871748327154610176">2017年6月5日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

使い方は非常に簡単でFixBoxをhierarchyに追加しいくつかのプロパティを設定することで対応できます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/152548/379fd174-fc5c-29d4-3ffd-53d0d789a115.png)

#### プロパティ
プロパティはFitBoxコンポーネントの中の２つのプロパティ名になります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/152548/70ec8dea-869e-e757-c830-f6b53535d059.png)

| プロパティ名 | 説明 |
|:-:|:-:|
| Move Collection On Dismiss | この設定にチェックが入っている場合はFitBoxをタップした場所にStartup Objectを配置されます。チェックがない場合はStartup Objectの初期値に設置されます。配置に関してはx軸方向のRotationは無視されます。また、y軸方向のpositionは元のStartup Objectと同じ値が設定されます（例えば見上げた状態でタップしてもオブジェクトの配置の高さは変わらないということです） |
| Startup Object | タップ後に表示するオブジェクトです。Hierarchyに存在するオブジェクトを指定します。アプリケーション起動時にFitBoxによって非表示になります。 |

### Progress

ロード時や長い処理の時に出すアニメーションです。俗にいうProgress Bar形状のものから色々作ることができます。例えば以下のようなものがさっと使えます。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">MRDesignLabsの練習その3。アニメーションでローディング。 <a href="https://t.co/NjUHZ98A3P">pic.twitter.com/NjUHZ98A3P</a></p>&mdash; takabrz (@takabrz1) <a href="https://twitter.com/takabrz1/status/878563052580356096">2017年6月24日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">MRDesignLabsの練習その１。Orbでローディング。 <a href="https://t.co/q0j5qoEoaa">pic.twitter.com/q0j5qoEoaa</a></p>&mdash; takabrz (@takabrz1) <a href="https://twitter.com/takabrz1/status/878562113072975872">2017年6月24日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>




使い方としてはProgress.PrefabをHierarchyに追加してプロパティの設定を実装を行います。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/152548/df1e4432-84f1-8883-ece7-c9017dd12bb5.png)




#### プロパティ
プロパティはLoadingDialogのコンポーネントの情報を変更します。変更するのは以下の部分になります。それ以外は基本的には変更不要です。接頭語がDefaultと書かれているプロパティは、実装中に変更可能です。

* Default Indicator Style
* Default Progress Style
* Default Message Style
* Default Prefab
* Defalut Icon
* Progress Format

![image.png](https://qiita-image-store.s3.amazonaws.com/0/152548/4788e713-fe15-9c64-1dbe-e27c9f818e6c.png)

| プロパティ名 | 説明 | 設定値など |
|:-:|:--|:--|
| Default Indicator Style | Progressの外観の種類を設定します。 | <ul><li>None</li><li>Static Icon</li><li>Animated Orbs</li><li>Prefab</li></ul>  |
| Default Progress Style  | 進行状況の外観を設定します。なし/プログレスバー形式/数値を選択します。  | <ul><li>None</li><li>Percentage</li><li>Progress Bar</li></ul>    |
| Default Message Style  | メッセージ表示を行うかを指定します。  | <ul><li>None</li><li>Visible</li></ul>  |
| Default Prefab  | Indicator StyleがPrefabの場合に使用されるオブジェクトを設定します。 |   |
| Defalut Icon | Indicator StyleがIConの場合に使用されるオブジェクトを設定します。  |   |
| Orbs Object  | Progress.Prefab内のOrbs Objectを指定します。  |   |
| Progress Bar Container  | Progress.Prefab内のProgress Bar Containerを指定します。  |   |
| Progress Bar  | Progress.Prefab内のProgress Barを指定します。  |   |
| ICon Renderer  | Progress.Prefab内のICon Rendererを指定します。  |   |
| Message Text  | Progress.Prefab内のMessage Textを指定します。  |   |
| Progress Text  | Progress.Prefab内のProgress Textを指定します。  |   |
| Animator  | Progress.Prefab内のAnimatorを指定します。  |   |
| Prgress Format  | Percentage表示の場合の数値フォーマットと指定します。  |   |

#### 実装例

実装例についてはMRDesignLabsの中にある「Progress_Examples」シーンにコードがありますので参考にしてください。ここでは基本的な処理方法について説明します。
実装の流れとしてはProgressの起動→コルーチンで状態更新→Progressの終了という流れになります。

##### Progressの起動
Progressの起動はLoadingDialog.Instance.OpenメソッドでProgressを実行状態にします。

```csharp

//Defaultの設定を使用して表示を行う。
LoadingDialog.Instance.Open("");//現行引数なし指定のものがない（後でIssueする）

//デフォルトの設定値を変更して呼び出す。(その1)
LoadingDialog.Instance.Open(
                        LoadingDialog.IndicatorStyleEnum.StaticIcon, // アイコン表示
                        LoadingDialog.ProgressStyleEnum.None, //状況表示なし
                        LoadingDialog.MessageStyleEnum.Visible, //メッセージ表示
                        );

//デフォルトの設定値を変更して呼び出す。(その2)
LoadingDialog.Instance.Open(
                        LoadingDialog.IndicatorStyleEnum.StaticIcon, // アイコン表示あり
                        LoadingDialog.ProgressStyleEnum.None, //状況表示なし
                        LoadingDialog.MessageStyleEnum.Visible, //メッセージ表示あり
                        LoadInMessage,
                        LoadInIcon
                        );

```

LoadingDialog.Instance.Openメソッドは以下のように定義されています。
このうち後ろ３つの変数については任意で設定になるので必要に応じて記述します。かなり柔軟な指定が可能ですのでアプリで一番使う定義を中心に必要に応じてアレンジするといった使い方になると思います。

##### コルーチン内での処理
Progressの起動後コルーチンで実際の処理を実装します。
コルーチン内でProgressの状態を変更する機能としてメッセージの変更と進行状況の変更が可能です。

```csharp
//表示メッセージを変更する
LoadingDialog.Instance.SetMessage(message);

//進行状態を設定する(0f～1f)
LoadingDialog.Instance.SetProgress(progress);
```

LoadingDialog.Instance.SetProgressメソッドに渡す値は0f～1fです。

##### Progressの終了
Progressの終了はコルーチンの最後でやります。実装は以下の通りです。
whileで待ちが入っているのですがこれはProgressの終了時にアニメーションが入っているのでそれの完了を待つために入ってるものです。

```csharp
LoadingDialog.Instance.Close();

while (LoadingDialog.Instance.IsLoading)
{
    yield return null;
}
```

### HelpText
アプリケーションでテキストのヘルプを表示することができるPrefabです。操作方法としてはデフォルトでは「H」でヘルプの表示、「J」で閉じます。表示されるテキスト別途作成したテキストファイルの内容を出力するようになっています。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/152548/c51b1f26-a5de-2875-7c45-943e77a09492.png)

#### プロパティ
プロパティはHelpTextコンポーネントの値を変更します。設定は以下の通りです。

| プロパティ名 | 説明 |
|:-:|:-:|
| Display Text Asset | 表示させるテキストファイルを設定します。 |
| Confidence Threshold  | 音声でコマンド入力の精度に関する閾値レベルを設定します。 |
| Show Help Key | ヘルプを表示するキーを設定します。 |
| Hide Help Key | ヘルプを閉じるキーを設定します。 |
| Show Help Text | ヘルプを表示する音声コマンドを設定します。 |
| Hide Help Text | ヘルプを閉じる音声コマンドを設定します。 |

### Dialog
アプリケーションでダイアログを作成したい場合に利用します。ダイアログについてはPrefabなどをHierarchyに追加する必要はなくプログラムで実装する形になります。
ダイアログを表示するために必要なクラス・オブジェクトは以下の通りです。

| クラス・オブジェクト | 説明 |設定値等|
|:-:|:--|:--|
| SimpleDialog | タイトル/メッセージ/ボタン領域を持つシンプルダイアログ ||
| SimpleDialogShell  |  HoloLensのシェルダイアログに似せたUIを持ちダイアログ ||
| SimpleDialog.ButtonTypeEnum | ダイアログのボタン種類を表す列挙値|<ul><li>SimpleDialog.ButtonTypeEnum.None</li><li>SimpleDialog.ButtonTypeEnum.Close</li><li>SimpleDialog.ButtonTypeEnum.Confirm</li><li>SimpleDialog.ButtonTypeEnum.Cancel</li><li>SimpleDialog.ButtonTypeEnum.Accept</li><li>SimpleDialog.ButtonTypeEnum.Yes</li><li>SimpleDialog.ButtonTypeEnum.No</li><li>SimpleDialog.ButtonTypeEnum.OK</li></ul>|

#### 実装例
ダイアログについてもサンプルが「SimpleDialog_Examples」シーンで最近追加されているので全コードはそれを参考にしてください。

流れとしては以下の形になります。

1. コルーチン内で処理を呼び出す
2. ダイアログを表示
3. ダイアログの終了を待つ

ダイアログ自体はモーダルで動作しているわけではないので、重複で処理が実施されないようにフラグなどで制御が別途必要になります。
呼び出しは以下のように実装します。

```Csharp
private IEnumerator LaunchDialog()
{
    var buttons = SimpleDialog.ButtonTypeEnum.Yes | SimpleDialog.ButtonTypeEnum.No;
    var title = "タイトル";
    var message = "ダイアログメッセージ";
    var dialog = (GameObject)Resources.Load ("MRDesignLab/HUX/Prefabs/Dialogs/SimpleDialogShell");
    SimpleDialog dialog = SimpleDialog.Open(dialog, buttons, title, message);
    dialog.OnClosed += OnClosed;

    //ダイアログクローズまで以降の処理を待つ
    while (dialog.State != SimpleDialog.StateEnum.Closed)
    {
        yield return null;
    }
}

private void OnClosed(SimpleDialogResult result)
{
    //クローズ時の処理を実装する。
}

```

ダイアログを表示はSimpleDialog.Openメソッドで実施します。
引数にはダイアログのPrefab,ボタン、タイトル、メッセージを設定します。
PrefabについてはSimpleDialogShellを指定します。これ以外のダイアログが必要な場合はSimpleDialogを継承し独自のPrefabを構成する必要があります。
ボタンは列挙値で表現されており、ダイアログに表示したいボタンの種類をOrでつなぎます。
ダイアログを閉じた時、その結果でなにか処理をさせるためにはdialogのOnClosedイベントにメソッドを登録します。