Pico neo2 のアイトラッキングデータがおかしくなる問題

Unity で作った Pico neo2 向けアプリでアイトラッキングデータを取得する際に、EyeTrackingData.leftEyeGazePoint.xNaN が入ってくる問題がありました。簡単に解決したのでその方法を説明します。

もともとこのようなスクリプトで Pvr_UnitySDKAPI.System.UPvr_getEyeTrackingData を使ってアイトラッキングのデータを取得していました。Tick は Zenject が提供する ITickable の、MonoBehaviour.Update と同じタイミングで呼ばれるメソッドです。もともとは MonoBehaviour のサブクラスとなっており、Update にしていたのですが、リファクタリングにあたって Zenject を使って書き直しました。その後から NaN が入る不具合が発生していました。

問題のコード

using Pvr_UnitySDKAPI;
using System.Collections.Generic;
using UnityEngine;
using Zenject;

public class EyeTracker: ITickable
{
    EyeTrackingData eyeTrackingData = new EyeTrackingData();

    public void Tick()
    {
        if (Pvr_UnitySDKEyeManager.supportEyeTracking)
        {
            var result = Pvr_UnitySDKAPI.System.UPvr_getEyeTrackingData(ref eyeTrackingData);
            if (!result)
            {
                Debug.LogWarning("Failed: UPvr_getEyeTrackingData");
            }
        }
    }
}

そこで LateUpdate に対応する LateTick を使うと、問題が発生しなくなりました。

解決したコード

using Pvr_UnitySDKAPI;
using System.Collections.Generic;
using UnityEngine;
using Zenject;

public class EyeTracker: ILateTickable
{
    EyeTrackingData eyeTrackingData = new EyeTrackingData();

    public void LateTick()
    {
        if (Pvr_UnitySDKEyeManager.supportEyeTracking)
        {
            var result = Pvr_UnitySDKAPI.System.UPvr_getEyeTrackingData(ref eyeTrackingData);
            if (!result)
            {
                Debug.LogWarning("Failed: UPvr_getEyeTrackingData");
            }
        }
    }
}

SDK 内の処理のため原因はわかりませんが、以下のようなことが起きているのではないかと想像されます。

  1. どっかでセンサー値をクリア(このときに呼び出すと NaN になる)
  2. デバイスからデータ読み取り

Update だと 1 〜 2 の間でアプリから値にアクセスしちゃう可能性があって、 LateUpdate だと 2 のあとに必ずアプリが値にアクセスするから値が取れる。