こんにちは、ZeniZeniです。
VR空間の移動方法って色々ありますけど、個人的にはタッチパッドでぐりぐり動くのが好きです。
自分のゲームで実装しようと思って方法を探したら、なかなかいいのが見つからなかったので自作しました。
動作環境
-Unity 2018.2.15f1
-SteamVR v1.2.3
使用するコード
TouchPadMove
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TouchPadMove : MonoBehaviour
{
private SteamVR_TrackedObject trackedObj;
private SteamVR_Controller.Device Controller
{
get { return SteamVR_Controller.Input((int)trackedObj.index); }
}
public enum MoveType
{
Walk,
WalkOnClick,
RotateOnClick,
}
public MoveType moveType;
[SerializeField]
private float Speed;
[SerializeField]
private Vector3 ChangeAngle;
[SerializeField]
private GameObject CameraRig;
[SerializeField]
private GameObject CameraEye;
#region TouchPadProperty
private bool TouchPadUp;
private bool TouchPadDown;
private bool TouchPadLeft;
private bool TouchPadRight;
#endregion
void Awake()
{
trackedObj = GetComponent<SteamVR_TrackedObject>();
}
void FixedUpdate()
{
if (moveType == MoveType.Walk)
{
if (Controller.GetAxis() != Vector2.zero)
{
Walk(Controller.GetAxis());
}
}
else if (moveType == MoveType.WalkOnClick)
{
if (Controller.GetPress(SteamVR_Controller.ButtonMask.Touchpad))
{
if (Controller.GetAxis() != Vector2.zero)
{
Walk(Controller.GetAxis());
}
}
}
else if (moveType == MoveType.RotateOnClick)
{
if (Controller.GetPressDown(SteamVR_Controller.ButtonMask.Touchpad))
{
Rotate();
}
}
if (Controller.GetAxis() != Vector2.zero)
{
TouchPadPositionCheck(Controller.GetAxis());
}
}
public Vector2 RotateMatrix(Vector2 TouchPosition)
{
float angle = (-CameraEye.transform.localEulerAngles.y - CameraRig.transform.localEulerAngles.y) * Mathf.Deg2Rad;
float x = TouchPosition.x * Mathf.Cos(angle) - TouchPosition.y * Mathf.Sin(angle);
float y = TouchPosition.x * Mathf.Sin(angle) + TouchPosition.y * Mathf.Cos(angle);
Vector2 RotatedVector = new Vector2(x, y);
return RotatedVector;
}
private void TouchPadPositionCheck(Vector2 TouchPosition)
{
float degree = Mathf.Atan2(TouchPosition.x, TouchPosition.y) * Mathf.Rad2Deg;
if (-30 < degree && degree < 30) TouchPadUp = true;
else TouchPadUp = false;
if (-180 < degree && degree < -150 || 150 < degree && degree < 180) TouchPadDown = true;
else TouchPadDown = false;
if (30f < degree && degree < 150f) TouchPadRight = true;
else TouchPadRight = false;
if (-150f < degree && degree < -30f) TouchPadLeft = true;
else TouchPadLeft = false;
}
private void Walk(Vector2 TouchPosition)
{
Vector2 RotatedVector = RotateMatrix(TouchPosition);
Vector3 MovePosition = new Vector3(RotatedVector.x * Speed, 0, RotatedVector.y * Speed);
CameraRig.transform.position += MovePosition;
}
private void Rotate()
{
var postPos = CameraEye.transform.position;
if (TouchPadRight)
{
CameraRig.transform.localEulerAngles += ChangeAngle;
}
if (TouchPadLeft)
{
CameraRig.transform.localEulerAngles -= ChangeAngle;
}
var currentPos = CameraEye.transform.position;
CameraRig.transform.position += (postPos - currentPos);
}
}
使い方
SteamVRをプロジェクトにインポートして、シーンに[CameraRig]と[Status]を置きます。
そして、[CameraRig]階層下のcontrollerに上のTouchPadMoveスクリプトをアタッチします。
CameraRig、CameraEyeにそれぞれ[CameraRig]、Camrera(eye)をアタッチしてください。
MoveTypeでWalkを選ぶと、タッチパッドを触るだけで移動します。
WalkOnClickを選ぶと、タッチパッドを押して移動します。
RotateOnClickを選ぶと、タッチパッドの右半分をクリックすると右に回転、左半分をクリックすると左に回転します。
Speedで移動速度が変わります。
ChangeAngleで回転時の回転角度が変わります。
どちらも最初0なので、適当な値を入れてください。
開発、執筆にあたり、下記のサイト様を参考、引用させていただきました。