HoloLensアプリ開発手順　備忘録 (ボタン機能(Compound Button、Interaction Receiverなど))

# はじめに
すでに沢山の方が開発手順の記事を記載してますが、個人の知識整理として投稿します。
HoloLens用アプリにおけるボタン追加、ボタン押下による処理について記載しています。
※2019/05/22時点の記事になります。

1.シーンにHolographic Buttonを追加する
2.InteractionReceiverを継承したスクリプトをアタッチしたオブジェクトを追加する
3.イベント処理を追加する

# 環境
Unity：2017.4.27f1 Personal(64bit)
MRTK：HoloToolkit-Unity-2017.4.3.0-Refresh.unitypackage

# シーンにHolographic Buttonを追加する
ProjectウインドウのHoloToolkit内のHolographicButtonをHierarchyウインドウに追加する。
※HolographicButtonは HoloToolkit/UX/Prefab/Buttons/の配下にある。

HolographicButtonにはCompound Buttonというスクリプトがアタッチしている。このCompound Buttonがボタンそのものを表すスクリプトで、このスクリプトによってボタンの状態がイベントとして送信される仕組みとのこと。Cubeなどのオブジェクトにこのスクリプトをアタッチすることで、色々なオブジェクトを「ボタン」として扱うことができる。
※Compound Buttonスクリプトは HoloToolkit/UX/Scripts/Buttons/の配下にある。

![compound.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401360/b630d178-8356-ac3e-734e-cc70a1fb395e.png)


# InteractionReceiverを使用してボタン押下イベントを処理する
HolographicButtonから送信されるイベントを処理するには、InteractionReceiverを継承したスクリプトをアタッチしたオブジェクトを作成する。

1.Hierarchyウインドウに空のGameObject(※)を追加する。
2.追加した空のGameObjectを選択し、Inspectorウインドウで「Add Component」で、新しいスクリプトを追加する。
3.追加したスクリプトを編集する。

```
using UnityEngine;
using HoloToolkit.Unity.Receivers;

public class Receiver : InteractionReceiver {   // InteractionReceiverを継承させる
}
```
4.InteractionReceiverを追加することで、UnityのInspectorウインドウのスクリプトに「Interactables」という項目が追加される。
![Interactables.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401360/06b47b28-70f5-3588-6d4a-105fa84255ec.png)
ここにはInteractionReceiverで受け取るイベントの送信元GameObjectを設定する。デフォルトではSize(送信元GameObjectの個数) : 0 となっている。この値を変更することでElement 0 ～　n が追加で表示されるようになる。このElementにHierarchyウインドウから送信元GameObjectをドラッグアンドドロップすることで設定する。

5.イベント発生時の処理を追加する。イベント発生時の処理は以下の様にinteractionReceiverで追加される各種メソッドをオーバーライドすることで実装する。

```
public class Receiver : InteractionReceiver {
    
    // メソッドをオーバーライドして処理を追加する
    protected override void InputClicked(GameObject obj, InputEventData eventData)
    {
        base.InputClicked(obj, eventData);
        
        // どのオブジェクトからのイベントかはobj.nameで判断できる
        switch (obj.name)
         ...
    }
}
```

今回はボタンのクリックイベントを使用したいので、InputClicked()メソッドをオーバーライドする(他にもFocusEnter()など様々なイベントが用意されている)。どのオブジェクトからのイベントかは引数objのフィールドobj.nameを参照することで判別できる。

# 使用例
今回はボタンを押下すると、キューブの色と、3Dテキストの文字が変わるサンプルを作成して動作を確認。

![scene.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401360/a229c5cc-8946-4e7f-9874-1fb95203533c.png)
![Receiver.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401360/6669926a-83bc-ad63-2c30-303442f587f2.png)

※キューブと3Dテキストを操作するためにプロパティとしてCube、DisplayMessageを持たせています。

```
using UnityEngine;
using HoloToolkit.Unity.Receivers;
using HoloToolkit.Unity.InputModule;

public class Receiver : InteractionReceiver {

    public GameObject Cube;
    private Renderer cubeRenderer;
    public GameObject DisplayMessage;
    private TextMesh dispMsgText;

    private bool flg = false;

    // Use this for initialization
    void Start()
    {
        cubeRenderer = Cube.GetComponent<Renderer>();
        dispMsgText = DisplayMessage.GetComponentInChildren<TextMesh>();
    }

    protected override void InputClicked(GameObject obj, InputClickedEventData eventData)
    {
        base.InputClicked(obj, eventData);

        switch (obj.name)
        {
            case "ButtonColorChange":

                // フラグ(true/false)の値でキューブの色、3Dテキストを赤・緑で切り替える
                if (flg)
                {
                    cubeRenderer.material.color = Color.green;
                    dispMsgText.text = "Green!";

                    flg = false;
                }
                else
                {
                    cubeRenderer.material.color = Color.red;
                    dispMsgText.text = "Red!";
                    flg = true;
                }

                break;

            default:
                break;
        }
    }
}
```

実行結果
ボタン押下でキューブの色と、3Dテキストが交互に切り替わった。

![red.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401360/1fec8b5d-c585-4e8f-5887-90155726e5ab.png)
![green.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401360/9ab075bf-4fa1-8e58-5b2e-7f33add417d1.png)