HTC VIVEでポジションリセンターを行う(UNITY)

Oculus Riftに比べて、HTC Viveのドキュメントは決して豊富とはいえません。
UnityのUnityEngine.VR.InputTracking.Recenter(); の関数が使えないなど、UnityのネイティブVRサポートも正しく動作しないことがあります。
例えば、作成中のゲームでStanding ModeやSeated Mode使おうとした場合SteamVRのValve.VR.OpenVR.System.ResetSeatedZeroPose ();
を利用することになるとおもいますが、Room-Scaleでのプレイヤー位置のリセットの場合はその関数は動かないことを前提としえいる為利用することができません。
そこでルームスケールでの位置リセットを実現するため、スクリプトを作成しましたのでシェアしたいとおもいます。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PositionRecenter : MonoBehaviour{

//必要な GameObjectをグラブします。
public GameObject avatar; //カメラリッグ
public GameObject eye; //カメラ
public GameObject[] hands; //両手

//ゲーム内のデフォルトポジションとスケールを設定します。
Vector3 defaultPos ;
public float defaultZ = 0f;
public float defaultY = 1f;
public float defaultX = 0f;

//ポジションOffsetを0に設定します。
float yDis=0f;
float xDis=0f;
float zDis=0f;

void Start (){

/*ゲームスタートのとき defaultPosを決めた
ゲーム内のスタート位置のデフォルト座標をX,Y,Zとして与えます。
パブリックフロートなのでインスペクターから変更可能です。
最後にSetPosの関数でゲームスタートのときポジションを
ゲーム内の初期ポジションにリセンターします。*/

defaultPos = new Vector3 (defaultX, defaultY, defaultZ);
SetPos ();
}

void Update (){

//In Gameでリセンターする場合矢印「↑」
if (Input.GetKeyDown (KeyCode.UpArrow)){
SetPos ();
}
}

public void SetPos(){

/*プレイヤーの頭のポジションと デフォルトポジション(ゲーム内での初期位置)のOffsetから計算しAvatarのポジションにoffsetの値を加えるとプレイヤーの位置とゲーム内での初期位置を合わせることができます。
Avatarのポジションはプレイヤーの現在の頭の位置の座標。*/

yDis = defaultPos.y - eye.transform.position.y;
xDis = defaultPos.x - eye.transform.position.x;
zDis = defaultPos.z - eye.transform.position.z;
avatar.transform.position = avatar.transform.position + new  Vector3 (xDis, yDis, zDis);

//手のポジションを、Avatarと一緒に移動します。
foreach (GameObject h in hands){
h.transform.position = h.transform.position + new Vector3  (xDis, yDis, zDis);
}
}
}

上記のスクリプトでは、VRの体験者はPlayRoomのRoomScale内のどこでもいても、ゲームを起動するとスタートの際、ゲーム内の初期ポジションに配置されます。
そしてゲーム始まった後、またその決めた場所に戻させるスクリプトです。
ゲームが一旦始まった場合でも矢印↑キーをおせば、ゲームの初期ポジションに戻すことができます。
細かい部分についてはまた次回に説明したいと思います。