DEV Community

松本隆介
松本隆介

Posted on

2 2

MagicLeapのEyeトラッキングの使い方( 超簡単サンプル )

開発環境

SDK等 バージョン
OS Windows10
Unity 2019.3.7f1
LuminOS 0.98.11
LuminSDK 0.24.1
MagicLeap-ToolKit 2020/09/27時点での最新( 特にバージョン表記がない為 )

サンプル動画

Eyeトラッキングのチョットしたサンプル作ってみた pic.twitter.com/C8afUckEHO

— 松本隆介 (@matsumotokaka11) October 1, 2020

なおこのサンプルはアプリの停止処理を入れてないので別途導入するか或いはThe Labからアプリを停止することをお勧めします

今回のサンプルはこちらのリポジトリ、EyeTrackingシーンに作成してあります

シーン構成

今回は超簡単サンプルということでシーンの構成も簡単にしました
scene

スクリプト

今回のサンプルでは右目の目線の先に青いキューブ、左目の目線の先に赤いキューブを配置し、瞬きしたら効果音を鳴らすサンプルです

using UnityEngine;
using UnityEngine.XR.MagicLeap;

namespace EyeTracking
{
    public class EyeTrackingSample : MonoBehaviour
    {
        readonly float TargetDistance = 2f;

        [SerializeField] Transform leftEyeTarget;
        [SerializeField] Transform rightEyeTarget;
        [SerializeField] AudioSource audioSource;
        [SerializeField] AudioClip blinkSound;


        void Start()
        {
            MLEyes.Start();
        }


        void OnDestroy()
        {
            MLEyes.Stop();
        }


        void Update()
        {
            if (!MLEyes.IsStarted) return;

            switch (MLEyes.CalibrationStatus)
            {
                case MLEyes.Calibration.Bad:
                    leftEyeTarget.gameObject.SetActive(false);
                    rightEyeTarget.gameObject.SetActive(false);
                    break;

                case MLEyes.Calibration.Good:
                    leftEyeTarget.gameObject.SetActive(true);
                    rightEyeTarget.gameObject.SetActive(true);
                    leftEyeTarget.position = MLEyes.LeftEye.Center + (MLEyes.LeftEye.ForwardGaze.normalized * TargetDistance);
                    rightEyeTarget.position = MLEyes.RightEye.Center + (MLEyes.RightEye.ForwardGaze.normalized * TargetDistance);

                    if ((MLEyes.LeftEye.IsBlinking || MLEyes.RightEye.IsBlinking) && !audioSource.isPlaying)
                        audioSource.PlayOneShot(blinkSound);
                    break; 

                case MLEyes.Calibration.None:
                    leftEyeTarget.gameObject.SetActive(false);
                    rightEyeTarget.gameObject.SetActive(false);
                    break;
            }

        }
    }
}

Enter fullscreen mode Exit fullscreen mode

コードの解説

Start()にあるMLEyes.Start()でEyeトラッキング用のモジュールを起動します

void Start()
{
    MLEyes.Start();
}

Enter fullscreen mode Exit fullscreen mode

OnDestroy()でモジュールを停止します

void OnDestroy()
{
    MLEyes.Stop();
}
Enter fullscreen mode Exit fullscreen mode

メインの処理はこちらになります
Update()では一応モジュールが起動していない場合は処理をスキップするようにしておきます

void Update()
{
    if (!MLEyes.IsStarted) return;

    switch (MLEyes.CalibrationStatus)
    {
        case MLEyes.Calibration.Bad:
            leftEyeTarget.gameObject.SetActive(false);
            rightEyeTarget.gameObject.SetActive(false);
            break;

        case MLEyes.Calibration.Good:
            leftEyeTarget.gameObject.SetActive(true);
            rightEyeTarget.gameObject.SetActive(true);
            leftEyeTarget.position = MLEyes.LeftEye.Center + (MLEyes.LeftEye.ForwardGaze.normalized * TargetDistance);
            rightEyeTarget.position = MLEyes.RightEye.Center + (MLEyes.RightEye.ForwardGaze.normalized * TargetDistance);
            if ((MLEyes.LeftEye.IsBlinking || MLEyes.RightEye.IsBlinking) && !audioSource.isPlaying)
                audioSource.PlayOneShot(blinkSound);
            break; 

        case MLEyes.Calibration.None:
            leftEyeTarget.gameObject.SetActive(false);
            rightEyeTarget.gameObject.SetActive(false);
            break;
    }

}

Enter fullscreen mode Exit fullscreen mode

目のキャリブレーションの状態が悪い時とそもそものキャリブレーションが取れていないときはターゲットとなるオブジェクトを非表示にしています
キャリブレーションが取れている場合は左右それぞれの目の正面方向( 今回は2m前方 )にオブジェクトを配置し、瞬きをしたら効果音を再生するようにしています


if ((MLEyes.LeftEye.IsBlinking || MLEyes.RightEye.IsBlinking) && !audioSource.isPlaying)
    audioSource.PlayOneShot(blinkSound);
Enter fullscreen mode Exit fullscreen mode

勘のいいひとはこれで気づくかもしれませんが瞬きの判定は瞬きした瞬間ではなく瞼を閉じている間になっています、そのため効果音を再生中は効果音を再生しないようにして多重に再生されるのを防いでいます
しばらく目をつぶっているとキャリブレーションの判定がNoneに遷移して処理がスキップされるようになります


簡単なMLEyes周りの紹介

MLEyesは左右の目の情報を管理するクラスです、これ自体はシングルトンクラスなのでインスタンス化の必要はなく左右それぞれの目へのアクセスも

MLEyes.LeftEye
MLEyes.RightEye
Enter fullscreen mode Exit fullscreen mode

このメンバーでアクセスが可能です

アイトラッキングのキャリブレーションの状態は以下のようにアクセスできます


switch (MLEyes.CalibrationStatus)
{
    case MLEyes.Calibration.Bad:
        // キャリブレーションの状態が悪い.
        break;

    case MLEyes.Calibration.Good:
        // キャリブレーションの状態が良好.
        break; 

    case MLEyes.Calibration.None:
        // キャリブレーションできていない.
        break;
}


Enter fullscreen mode Exit fullscreen mode

API Referenceにはこのように記述されています
Cariblation


The Labから見られるAPIのドキュメントバージョンが更新されていないのかMLEyeについての情報が手探りですが簡単な紹介を以下にしておきます

API Referenceを参照したい場合はDeveloper Portalの方を参照したほうがいいですね
尚左目のみ紹介します( 右目のプロパティ等も同様の構成の為 )

MLEyes.LeftEye.Center
Enter fullscreen mode Exit fullscreen mode

目の中心座標

MLEyes.LeftEye.Gaze
Enter fullscreen mode Exit fullscreen mode

目の回転Gazeとありますが視線の方向を撮りたいときは以下のプロパティから取得したほうが直感的です、本サンプルでもこちらを利用しています

MLEyes.LeftEye.ForwardGaze
Enter fullscreen mode Exit fullscreen mode

目のタイプ、右か左かのタイプです
現時点で既にプロパティとしてLeftEye、RightEyeとあるので利用することは無いと思います

MLEyes.LeftEye.Type
Enter fullscreen mode Exit fullscreen mode

アイトラッキングの情報の信頼性
0 で目を閉じているまたはデバイスをかぶっていない、最初の更新時は0で初期化されています

MLEyes.LeftEye.CenterConfidence
Enter fullscreen mode Exit fullscreen mode

瞬きしているか否か、trueで瞬き( どちらかというと瞼を閉じている )の判定になります

MLEyes.LeftEye.IsBlinking
Enter fullscreen mode Exit fullscreen mode

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay