Hololens2でアイトラッキングをしてみた


MRTKで視線認識(アイトラッキング)を使用したいが実装方法が分からない方が対象になっています。
使用方法を理解するために、VRMモデルを配置し、視線認識(アイトラッキング)をトリガーとして使い、モデルを動作させる流れを実装します。
## **実装環境**
Unityバージョン 2019.4.17f1
MRTK2.5

MRTK2.5の環境が整っていなければ、[**こちらの記事**](https://qiita.com/chomado/items/ff21e57aa563191f3be0)を参考にインポートしてみてください。
## **準備するもの**  
**1.VRMモデル**
・VRMモデルの作成
こちらは[**VroidStudio**](https://vroid.com/)で簡単に作成することが出来ます。
サンプルモデルから好きなモデルを選択→撮影・エクスポート(上段タブ)→エクスポート(左ペイン)
設定は適当で構いません。
・[**UniVRM**](https://github.com/vrm-c/UniVRM/releases)をインポート
こちらはUnityでVRMモデルを出力させるために必須であるため、インポートする必要があります。

**2.アニメーション**
VRMモデルに対して、アニメーションを付与するために、既存のアニメーションを持ってきます。今回付与するアニメーションは「しゃがむ」です。
Standard Assets (for Unity 2018.4)をAsset Storeからインポートします。
インポート後．．．
・ThirdPersonAnimatorController.controller　と下図のファイルが必要なので、他のファイルは削除します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/824949/9faf5463-2aad-6c3c-3fa4-45e03a316d99.png)
## **実装**
まず初めに、[**公式リファレンス**](https://docs.microsoft.com/ja-jp/windows/mixed-reality/develop/unity/tutorials/mr-learning-base-08)を参考に視線認識の設定をします。
VRMモデルをインポートしたら、VRMモデルにAnimatorをAdd Conponentします。
AnimatorのcontrollerはThirdPersonAnimatorController.controllerを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/824949/16856ad6-8fa5-5a45-faa4-fb1ba2fb9d46.png)
Rigidbody、Capsule ColliderもAdd Conponentして、下図のように設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/824949/7aa8f946-7a4c-61c7-b443-6a6f9ee50459.png)
VrmAnimationという名前でスクリプトを作成します。このスクリプトはAnimatorで設定されている「しゃがむ」動作に対してTrueかFalseを渡してAnimatorをコントロールする役割を持っています。
今回のメインは視線認識がであるため、説明は割愛させていただきます。

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(CapsuleCollider))]
[RequireComponent(typeof(Animator))]
public class VrmAnimation : MonoBehaviour
{
    Rigidbody m_Rigidbody;
    Animator m_Animator;
    CapsuleCollider m_Capsule;
    bool m_Crouching;

    // Start is called before the first frame update
    void Start()
    {
        m_Animator = GetComponent<Animator>();
        m_Rigidbody = GetComponent<Rigidbody>();
        m_Capsule = GetComponent<CapsuleCollider>();
        m_Rigidbody.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY | RigidbodyConstraints.FreezeRotationZ;
        m_Crouching = false;
        Invoke("SetCrouch", 3.5f);
    }

    // Update is called once per frame
    public void SetRun()
    {
        m_Animator.SetFloat("Forward",0.1f, 0.1f, Time.deltaTime);
        m_Animator.SetFloat("Turn", 0.1f, 0.1f, Time.deltaTime);
    }
    public void SetCrouch()
    {
        if (!m_Crouching)
        {
            m_Crouching = true;
            m_Animator.SetBool("Crouch", m_Crouching);
        }
        else
        {
            m_Crouching = false;
            m_Animator.SetBool("Crouch", m_Crouching);
        }
    }
}
```


MRTKで用意されているEyeTrackingTargetをAdd Conponentします。
EyeTrackingTargetのOn Look At Startで下図のような設定を行います。今回はOnLookAtStartのみを使用していて、先ほどのスクリプト(VrmAnimation)で作成したメソッドが呼び出されるよう設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/824949/358f6973-b97d-54f7-5122-5180b130dc26.png)
EyeTrackingTargetの機能の説明として、
**OnLookAtStart**：ユーザーがターゲットを見始めたときにトリガーされます。
**OnLookAway**：ユーザーがターゲットから目をそらしているときにトリガーされます。
**OnDwell**：ターゲットが指定された、事前定義された期間（dwellTimeInSec）にわたって調べられたときにトリガーされます。
**OnSelected**：見たターゲットが選択されると、イベントがトリガーされます。
**OnTapDown**：RaiseEventManually_TapDownが呼び出されると、イベントがトリガーされます。
**OnTapUp**：RaiseEventManually_TapUpが呼び出されると、イベントがトリガーされます。

## **検証**
Hololensにデプロイします。
**視線を合わせる前**が左の画像の状態、**視線を合わせた後**が右の画像の状態になっていれば**成功**です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/824949/afbb37e9-7389-6aa8-8ab4-0cb9849b73b6.png)