こんにちは! VR事業部の長谷川(id:waffle_maker)です。 前回はFOVE0の開封と準備でしたが、今回はUnityを使って色々と動かしてみます。
まずはキャリブレーションを実行
FOVEとPCを接続してランタイムを起動します。FOVEとPCは、HDMIケーブル1本、USBケーブル2本で接続します。
次に、前回の記事で記載した通り、タスクトレイにあるFOVE VRアイコンを右クリックし、「設定ツールの起動」を選択します。
FOVEが接続されると上の画像の赤枠で囲んだ部分は、「ランタイムの停止」になっています。 もし、「ランタイムの開始」になっている場合は、ランタイムがまだ起動していないので、この場所をクリックして起動させます。
この状態でFOVEをかぶると、キャリブレーションを実行する画面が出ます。 キャリブレーションでは、目の前に出てくる緑色の球がゆっくり移動するので、それに合わせて視線を動かします。 1分程度で終わり、「キャリブレーションに成功しました。」という文字が出ると完了です。
Unity向けファイルは3種類
2017/05/03時点で、FOVEのDeveloperページには、Unityに関するファイルが3種類あります。
以下、個別に解説します。
[1] Unityで作られたアプリケーション「EXAMPLE_CONTENT」を確認
まずは、EXAMPLE CONTENT というリンクをクリックして、サンプルアプリケーションを試してみます。 FOVEを接続してからexeを実行すると、このような画面が出ます。
これは、部屋の中で視線の動きだけでライトを点灯、消灯させるデモです。
画像の中心にある緑色とピンク色の球が、自分の左右の眼の動きに合わせて動きます。壁にある小さな水色の球がスイッチです。
視線を動かし、緑かピンクの球を壁のスイッチに当てると、ライトが点灯します。もう一度当てると消灯します。
部屋の中の移動はできませんが、ポジショントラッキングカメラがあるので、そばに置いてあるテーブルに近づくことは可能です。
なお、ポジショントラッキングカメラは、OSVR1.3に付属していたカメラと同一ハードウェアでした。
[2] Unityのサンプルプロジェクト「UNITY_EXAMPLE」を確認
Unity5.5以上という指定があるので、先にver 5.5以降のUnityをインストールしておきます。
サンプルプロジェクトをUnityで開くと、このようなWarningが出ます。
ここで、ContinueをクリックするとUnityが開きます。 ただし、下記のWarningが出ています。
これらの原因は不明ですが、FOVEを動作させることができたので詳細は未調査です。
では、サンプルシーンを解説します。 SampleSceneというシーンを開くと、このような画面になります。
Hierarchy ViewにあるSceneと書かれているオブジェクトは、部屋のモデルを集めたものです。
Fove Rigの子オブジェクトである、Fove Interfaceオブジェクトおよびコンポーネントが処理の中心です。
Fove Interfaceコンポーネントは、FOVEで視線入力を検出すると、FoveInterface.IsLookingAtColliderというメソッドで検出したことを通知します。 例えば、視線で見つめたものを変化させたいときは、変化させたいオブジェクトでFoveInterface.IsLookingAtColliderを呼ぶことで、視線入力を知ることができます。
今回のデモでは、部屋にあるCubeオブジェクトにアタッチされているFove Look Sampleスクリプトが、FoveInterface.IsLookingAtColliderを呼んでいます。
視線で見つめるとCubeが光る処理は下記の通りです。
/* FOVELookSample .csの一部*/ // Update is called once per frame void Update () { if (FoveInterface.IsLookingAtCollider(my_collider)) { if (light_enabled) { l.enabled = true; m.SetColor("_EmissionColor", l.color); DynamicGI.SetEmissive(GetComponent<Renderer>(), l.color); m.EnableKeyword("_EMISSION"); } //bool check = FoveInterface.IsLookingAtCollider(my_collider); } else { gameObject.GetComponent<Renderer> ().material.color = Color.white; //GetComponent<Renderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On; m.DisableKeyword("_EMISSION"); if (light_enabled) { l.enabled = false; DynamicGI.SetEmissive(GetComponent<Renderer>(), Color.black); } } }
また、Fove Interfaceの子オブジェクトには、SphereLeftとSpeherRightというオブジェクトがあり、ここにアタッチされているスクリプトにより Sphereオブジェクトの位置を検出することができます。
/* FOVE3DCursorLeft .csの一部*/ void Update() { FoveInterface.EyeRays rays = FoveInterface.GetEyeRays(); // TODO: calculate the convergence point in FoveInterface // Just hack in to use the left eye for now... RaycastHit hit; Physics.Raycast(rays.left, out hit, Mathf.Infinity); if (hit.point != Vector3.zero) // Vector3 is non-nullable; comparing to null is always false { transform.position = hit.point; } else { transform.position = rays.left.GetPoint(3.0f); } }
なお、現状のサンプルプロジェクトを調べた限りでは、FoveInstanceクラスのAPIは視線入力の結果を取得するget系の関数のみであり、何らかの値を設定するset系の関数は準備されていないため、視線入力の微調整は難しそうという印象を持ちました。
参考までに、FoveInstanceの定義を開いて、APIの一覧を下記に書き出しました。 Fove SDKのAPI一覧は、下記に掲載されています。
http://docs.getfove.com/unityapi/namespaces.html
#region Assembly FoveUnityPlugin, Version=0.5.6269.32729, Culture=neutral, PublicKeyToken=null // <in-memory assembly> #endregion using System; using Fove; namespace UnityEngine { public class FoveInterface : MonoBehaviour { public FoveInterface(); public static EFVR_Eye CheckEyesClosed(); public static bool CheckSoftwareVersions(out string error); public static bool EnsureEyeTrackingCalibration(); public static string GetClientVersion(); public static EyeRays GetEyeRays(); public static GazeConvergenceData GetGazeConvergence(); public static Vector3 GetHMDPosition(); public static Quaternion GetHMDRotation(); public static SFVR_Pose GetLastPose(); public static Camera GetLeftEyeCamera(); public static Vector3 GetLeftEyeVector(); public static Vector3 GetNormalizedViewportPosition(Vector3 pos, EFVR_Eye eye); public static Camera GetRightEyeCamera(); public static Vector3 GetRightEyeVector(); public static string GetRuntimeVersion(); [Obsolete("Please use IsEyeTrackingCalibrated instead")] public static bool IsCalibrated(); public static bool IsEyeTrackingCalibrated(); public static bool IsEyeTrackingCalibrating(); public static bool IsHardwareConnected(); public static bool IsHardwareReady(); [Obsolete("You should get a reference and use the non-static version of this function.")] public static bool IsLookingAtCollider(Collider col); public static void TareOrientation(); public static void TarePosition(); public void ConnectCompositor(); public void DisconnectCompositor(); public struct EyeRays { public Ray left; public Ray right; public EyeRays(Ray l, Ray r); } public static class Version { public const int MAJOR = 1; public const int MINOR = 1; public const int RELEASE = 1; } } }
[3] UnityのSDK「UNITY_PACKAGE」を確認
最後に、unitypackage形式のファイルを確認します。 Unityで新規プロジェクトを作り、unitypackageをインポートすると、先ほどのサンプルプロジェクトでも登場したFoveUnityPluginフォルダのみがAssetsフォルダに展開されます。
unitypackageのみを展開した場合
Unityのサンプルプロジェクトの場合
ざっと見る限りでは、それぞれのFoveUnityPluginフォルダの中身は同じでした。
ただし、視線の動きに合わせてオブジェクトを動かすには、sphereなどの適当なオブジェクトを準備し、[2]のサンプルプロジェクトに入っていたFOVE3DCursorRight.csとFOVE3DCursorLeft.csをアタッチする必要がありますが、これは[2]のみに入っています。 そのため、視線の動きを表示させたいときは、この2つのスクリプトを使う必要があります。
なお、「UNITY_PACKAGE」をダウンロードすると、pdfのマニュアルも同梱されているので、詳細はそちらをご確認ください。
終わりに
今回、一通りの使い方を整理しながら、UnityサンプルプロジェクトだけでなくFOVEのHPで提供されているサンプルアプリも試しました。 コントローラを持たず、首を振らなくても操作ができる視線入力は、VRにおいて新しい入力手段になりそうで、とても可能性を感じました。
一方、弊社で試した限りでは、現状のFOVEは視線認識の精度が不安定なところがあり、開発者キットであるという印象を持ちました。 弊社ではFOVEに限らずVRの案件に広く対応できますので、ご興味あればお気軽にお問い合わせください。