Bakulog

獏の夢日記的な何か。

Tobii Eye TrackerとUnityでランチャーソフト的なものを作る

まだ完成してませんが書けるレベルで知識ついたので書きます。

もくじ

  1. Tobii Eye Trackerとは何者か
  2. なぜランチャーソフトなのか
  3. TobiiのAPIを使ってみる(他記事紹介がメイン)
  4. デスクトップアイコンへの注視を検出する
  5. その他やってる細かい事
  6. 今後
  7. ライセンス

 

要約

要約というか、4ステップに分けて経緯をさくっと紹介します。

1ステップ目、Tobii Eye Tracker 4Cなるデバイスを買いました。

https://twitter.com/baku_dreameater/status/920271623919243264

 

2ステップ目、サンプルで勉強しながらUnityで動かしました。

https://twitter.com/baku_dreameater/status/921639638590136320

 

3ステップ目、視線で制御するよいUIの方針が分からなかったので適当にこしらえました。

https://twitter.com/baku_dreameater/status/921725593032331264

 

4ステップ目、デスクトップアイコンをたたいて動かしました。

https://twitter.com/baku_dreameater/status/922074014603866113

 

本記事では4ステップ目の動画にある、「デスクトップのアイコンをたたいて動かす」という処理について紹介します。 なお、本記事の適用先はWindowsのみを想定しています。

 

1. Tobii Eye Trackerとは何者か

Tobii Eye Trackerというのは、Tobii Technology社が出している視線トラッキングバイスです。 Tobiiは様々な視線トラッキングバイスを売ってますが、 本記事では低価格なTobii Eye Tracker 4Cを使っています。 参考として、価格帯が近いデバイスはこんな感じ。

測定原理にもよりますが、視線トラッキングは概してヘッドマウントディスプレイ(HMD)と相性が悪くなりがちで、 VRが盛り上がってきたことによって相対的に少し目立たなくなっていました。 とはいえデバイス的には普通に面白みがありますし、今後も注目すべきジャンルだと思っています。

 

2. なぜランチャーソフトなのか

視線トラッキングで出来ることは色々ありますが、 ランチャーソフトを作ろうと思った理由は以下のとおりです。

  • 個人的に常駐アプリ作るのが好き
  • ゲームを作るよりはハードルが低そう
  • ただし、視線に依存してキャラを動かすなど、インタラクション的にも楽しくする余地が大いにありそう
  • 普段は手でPC操作している人が一時的に手を使えないとき、視線でのUI制御はどこまで使えるか試したい

平たく言うと、気まぐれです。

 

3. TobiiのAPIを使ってみる

ここからちょっとだけ技術的な話題です。

※ここではTobiiの一般ユーザー向けの準備については手順を省略し、できているという前提で進めます。

まずSDKTobiiのデベロッパー向けページから探せば手に入ります。

ここでは以下の2つを使います。

  • .NET向け: VSでソリューション作成後、Nugetパッケージマネージャで取得
    • Tobii.InteractionTobii.Streamingの二種類がある
    • サンプルはGitHubのsample以下にあるので見る
  • Unity向け: UnitySDK(GitHub)にあるので取得

いずれについても「サンプル読んでマネすれば動くからサンプル読んで下さい」というのがここでのアドバイスとなります。 サンプルはそこそこあるので私からはナニモイウコトハナイ

 

4. デスクトップアイコンへの注視を検出する

このような要件を考えます。

ユーザーがどのデスクトップアイコンを注視しているのか(当然どのアイコンも見ていない場合も含む)をプログラムから取得したい。

この要件は2つのタスクに分けられます。

  • デスクトップアイコンの一覧を列挙し、アイコンの領域(位置と幅、高さ)を取得する
  • Tobii Eye Trackerを使って、ユーザーがデスクトップ上のどこを見ているかを取得する

前者のデスクトップアイコンの領域取得はTobiiと無関係であり、前の記事で紹介しています。

問題は後者の、Tobii Eye Trackerでデスクトップ画面上のどこを見ているかを検出するほうです。 Unity向けのSDKではGazePointというのを使って凝視先の座標が得られるのですが、 このGazePointはUnity画面座標に変換された値になっているので、 デスクトップ座標にはそのまま変換できません。

この問題を解決する方法はいくつか考えられますが、 ラクちんな方法として.NETのコンソールアプリケーションを別に作ってしまう手が挙げられます 具体的な手順としては、まずコンソールアプリケーションを作り、NuGetで以下2つのライブラリを参照します。

そして、このようなプログラムを書きます。

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using Tobii.Interaction;

namespace TobiiStreamOnConsole
{
    class Program
    {
        static UdpClient _udpClient;

        static void Main(string[] args)
        {
            using (var host = new Host())
            {
                _udpClient = new UdpClient();
                var stream = host.Streams.CreateGazePointDataStream();
                stream.GazePoint(OnGazePointUpdate);
                Console.ReadLine();
            }
        }

        static void OnGazePointUpdate(double x, double y, double timeStamp)
        {
            byte[] data = Encoding.UTF8.GetBytes(
                $"{x:0.000},{y:0.000},{timeStamp:0.000}"
                );

            _udpClient.Send(data, data.Length, new IPEndPoint(IPAddress.Loopback, 54321));
        }
    }

}

上記プログラムでOnGazePointUpdateに渡される(x, y)がデスクトップ座標であり、 それをUDPとかで投げてしまえば、あとはUnityのほうで受け取ってどうにでも出来る、というわけです。

 

5. その他やってる細かい事

箇条書きでいちおう書くだけ書いておくので、詳細気になる人はコメントで聞くかググって下さい。

  • 視線で注目している所を追ってくれるキャラとしてクエリちゃんに入っていただく
  • SDKに含まれるGazeAwareスクリプトは、2DのUIオブジェクトより3Dオブジェクトと相性がよいので、Cubeとかボタンオブジェクトを作る
    • 今回は「手を使わない」という事にこだわったため、一定時間同じところを見ると反応するようなUIにしました1
    • ボタンを凝視し続けるとゲージが溜まる、という表現はMaterialのOffsetをいじって実現しています。
    • ボタンは常時出ていなくても良さそうなので、クエリちゃん付近を見つめたときに限り出現させています。これをするにはクエリちゃんの正面に透明なオブジェクトを置き、ColliderとGazeAwareをアタッチすれば何かしら処理できるようになります。

 

6. 今後

今後のマイルストーンはハッキリと決まっていて、 年内にはマスコットアプリ文化祭に出します。 キャラクターにクエリちゃんを採用し、Tobii Eye Trackerを使っているのには、 クエリちゃん賞(VR or ハイテク系のなんかが対象)を取りたいなあという背景があったりなかったりします。

私が本ブログに書いてる話題の中ではめずらしく納期が明確(年内リリースがほぼ必須)なので、 リリースの時になったらまた記事に書こうと思います。

 

7. ライセンス

ツイートにも出てきますし記事中でも触れていますが、ここで紹介したソフトはクエリちゃんを使用しています。

以上です。


  1. 「同じところを見続けるとボタンライクに反応するUI」というのはR18ゲーのVRカノジョで初めて知ったスタイルです。この場で名前を出させていただいて謝辞とします。