GVR SDKを使った視線入力のためのTips

#はじめに
VRアプリケーションにおける入力方法の1つに視線入力があります。視線入力を実装する手段はいくつかあると思うのですが、今回はGoogleVR SDKのアセットを使った方法をについてまとめたいと思います。比較的コードの記述が少ない方法だと思うので、割と簡単に導入できるのではないでしょうか。

#今回の成果物
今回は視線入力の実装の練習として、動画のような一定時間見つめるとターゲットの色がランダムに変わるというアプリケーションを作っていきたいと思います。ターゲットを回転させているのは少しでも見栄えを良くしようとした結果で、それ以外特に意味はありません笑
![GVRPointerTest.gif](https://qiita-image-store.s3.amazonaws.com/0/245462/0768f4ee-e213-862c-00ac-05887c51a1c6.gif)

#動作環境
- macOS High Sierra 10.13
- Unity 2018.2.14f1
- GVR SDK for Unity v1.130.1

#実装手順
1. [GVR SDK for Unity](https://github.com/googlevr/gvr-unity-sdk/releases)からunitypackageをダウンロードしてきて、UnityのAssetsにインポートします。

2. HierarchyにGvrEditorEnumelatorを置きます。GoogleVR/Prefabsにあります。Main Cameraと同じ階層で大丈夫です。

3. Main Cameraの直下にGvrReticlePointerを置きます。GoogleVR/Prefabs/CardBoardにあります。

4. HierarchyのMain Cameraと同じ階層GvrEventSystemを置きます。GoogleVR/Prefabs/EventSystemにあります。

5. Main CameraにPhysics Raycasterコンポーネントをアタッチします。

6. 見つめる対象となるオブジェクトにEvent Triggerコンポーネントをアタッチします。

これでinspector上での設定はほぼ終了です。現段階でinspectorは以下のようになっています。
<img width="270" alt="スクリーンショット 2019-01-15 9.20.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/245462/920c33de-e6ff-b86e-3f92-3021844607cb.png">

GameControllerは後ほどスクリプトをアタッチするためのものです。続いてスクリプトを書いていきましょう。

``` cs:GameController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameController : MonoBehaviour {

    // 色を変えるターゲット
    public GameObject target;

    // 色を変えるまでの時間
    public float colorChangeTime = 3f;

    // 視線がターゲットを捉えているかを判定するもの
    bool flag;

    // 色を変えるまでの時間を管理するタイマー
    float timer;

	void Start () 
    {
        flag = false;
        timer = colorChangeTime;
	}
	
	void Update () 
    {
        // 特に意味はないけど回してみた
        target.transform.Rotate(new Vector3(0f, 0.8f, 0f));

        if (flag)
        {
            timer -= Time.deltaTime;
            if (timer < 0)
            {
                // タイマーをリセット
                timer = colorChangeTime;

                // ターゲットの色をランダムに変更
                float r = Random.Range(0f, 1f);
                float g = Random.Range(0f, 1f);
                float b = Random.Range(0f, 1f);
                Color afterColor = new Color(r, g, b);
                Debug.Log(afterColor);
                target.GetComponent<Renderer>().material.color = afterColor;
            }
        }
	}

    // ポインターがターゲットに入った時に実行される関数
    public void EnterToTarget()
    {
        flag = true;
    }

    // ポインターがターゲットから外れた時に実行される関数
    public void ExitFromTarget()
    {
        flag = false;
        timer = colorChangeTime;
    }
}
```

ポイントはスクリプト内で、ポインターがターゲットに入った時に実行する関数やターゲットから外れた時に実行する関数を定義しているところです。このスクリプトを先ほどのGameControllerにアタッチします。

7. 最後に今定義した関数をEvent Triggerに設定すれば終了です。TargetにアタッチしたEevnt TriggerのAdd New Event Typeをクリックし、PointerEnterとPointerExitを選択します。PointerEnterとPointerExit共にGameControllerオブジェクトを選択し、PointerEnterの方にEnterToTarget関数を、PointerExitの方にExitFromTarget関数を設定します。最終的にこうなります。　

<img width="365" alt="スクリーンショット 2019-01-15 19.45.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/245462/75762216-bc77-118f-fd03-00a300000cb4.png">

以上で全ての設定が完了です。

#おわりに
もう1つ代表的なものとしてRayを飛ばす方法が上げられます。
両者のメリットやデメリットなど比較できたら有意義かもしれませんね。
余裕があれば追記してみます〜