脳汁portal

アメリカ在住(だった)新米エンジニアがその日学んだIT知識を書き綴るブログ

UnityでOculusなどのHMDの向いてる方向を取得する方法

HMDの向いている方向を取得する方法です
Oculus Riftで確認しましたが、GearVRでも同じ処理で取得できるはずです

情報の取得

using UnityEngine;
using System.Collections;
using UnityEngine.VR;     // enable to get HMD direction

public class Direction : MonoBehaviour {
    void Update () {
        Quaternion direction = InputTracking.GetLocalRotation (VRNode.Head);
        Debug.Log (direction);
    }
}
  • HMDの情報をとるためにまずはUnityEngine.VRの利用を宣言します
  • 実際の情報取得はInputTracking.GetLocalRotationで行い、引数で右目や左目、中央などを指定できます。
    • Headは中央(CenterEye)と同じ値を返します

返り値

返り値は以下のような形になります
(float, float, float, float)

  • それぞれ[-1.0~1.0]の範囲の値を返します
  • 起動時からHMDを動かさないと(0.0, 0.0, 0.0, 1.0)を返します
  • (a, b, c, d)として
  • a
    • 首を縦に振る動きの取得
    • 上を向くとマイナス
    • 下を向くとプラス
  • b
    • 首を横に振る動きの取得
    • 左を向くとマイナス
    • 右を向くとプラス
    • 一回転(360度)以上は注意が必要(後述)
  • c
    • 首をかしげる動きの取得
    • 右にかしげるとマイナス
    • 左にかしげるとプラス

実際に方向の取得

using UnityEngine;
using System.Collections;
using UnityEngine.VR;     // enable to get HMD direction

public class Direction : MonoBehaviour { 
    void Update () {
        Quaternion direction = InputTracking.GetLocalRotation (VRNode.Head);

	// 前向き
	if (-0.25f <= direction [1] && direction [1] < 0.25f) {
	    Debug.Log ("center");
	// 後ろ向き
	} else if (direction [1] <= -0.75f || 0.75f <= direction [1]) {
            Debug.Log ("back");
	// 左向き
	} else if (0.25f <= direction [1] && direction [1] < 0.75f) {
            Debug.Log ("left");
	// 右向き
	} else if (-0.75f <= direction [1] && direction [1] < -0.25f) {
            Debug.Log ("right");
	}
    }
}

これで向いている方向を取得することができました。
しかしこれだけだと実はHMDが一回転以上すると右と左が反対になってしまいます。
前→右→後→左→前→(←本当は右にならなければいけない)

これを回避するためにdirectionの4つ目の値を利用します

using UnityEngine;
using System.Collections;
using UnityEngine.VR;     // enable to get HMD direction

public class Direction : MonoBehaviour {
    void Update () {
        Quaternion direction = InputTracking.GetLocalRotation (VRNode.Head);

	// 前向き
	if (-0.25f <= direction [1] && direction [1] < 0.25f) {
	    Debug.Log ("center");
	// 後ろ向き
	} else if (direction [1] <= -0.75f || 0.75f <= direction [1]) {
            Debug.Log ("back");
	// 左向き
	} else if (0.25f <= direction [1] && direction [1] < 0.75f) {
	    if (direction [3] < 0) {
		Debug.Log ("left");
	    }else{
	        Debug.Log ("right");
	    }
	// 右向き
	} else if (-0.75f <= direction [1] && direction [1] < -0.25f) {
            if (direction [3] < 0) {
		Debug.Log ("right");
	    }else{
		Debug.Log ("left");
	    }
	}
    }
}

これで何回転しても正しい方向を取得できるようになりました