GearVRアプリで、視線でメニューを選んだり、別売りのリモコンを使って操作するサンプルです。
(ビルド方法などは省略します。コチラが参考になります→ https://framesynthesis.jp/tech/unity/gearvr/ )
①視線入力で選択
向いた方向の視線で操作するサンプルです。
外付けのコントローラーがない場合は、
メニュー選択など様々な場面で使うことになると思います。
アセットのインポート
Unityが提供しているVR Sampleアセットは、VRアプリを作る上で必要な機能が詰め込まれていて勉強になります。
こちらからインポートして下さい。
https://www.assetstore.unity3d.com/jp/#!/content/51519
MainCameraの置き換え
まずはMainCameraをVR対応のものに置き換えます。
デフォルトのMainCamraを削除して
VRSampleScenes/Prefabs/Utils/MainCamera
に置き換えましょう。
このMainCamraには視線のターゲットとなる印や、キー入力をハンドルするスクリプトが組み込まれています。
MainCamera配下のGUIReticleが照準を示す点、UISelectionBarが照準が合っているときにギューンと増えるゲージです。
今回はゲージは必要ないので、UISelectionBarとBackgroundは無効にし、GUIReticleのImageだけ使うので有効にしておきます。
次に、Editorでの開発用にカメラをキーボードで動かせるようにしておきます。
以下のスクリプトをMainCameraにアタッチします。
これでEditorで開発中はカーソルで向いてる方向を変えることが出来ます。
public class EditorCameraRotation : MonoBehaviour
{
void Update()
{
#if UNITY_EDITOR
if (Input.GetKey(KeyCode.RightArrow))
{
this.transform.Rotate(0, 1, 0);
}
else if (Input.GetKey(KeyCode.LeftArrow))
{
this.transform.Rotate(0, -1, 0);
}
else if (Input.GetKey(KeyCode.UpArrow))
{
this.transform.Rotate(-1, 0, 0);
}
else if (Input.GetKey(KeyCode.DownArrow))
{
this.transform.Rotate(1, 0, 0);
}
#endif
}
}
対象のオブジェクトの配置
視線が合うと反応する対象のオブジェクトを作成します。
Cubeを適当な位置に配置し、
VRStarndardAssets/Scripts/VRInteractiveItem.cs
をCubeにアタッチします。
VRInteractiveItem.csは、先ほどのMainCameraが発するRayCastを受け取ってイベントを発行してくれるスクリプトになります。
視線が当たったときのアクション
先ほどのVRInteractiveItem.csの発行するイベントを受け取って、何らかのアクションをするようにしてみましょう。
Cubeに以下のスクリプトをアタッチします。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using VRStandardAssets.Utils;
public class ChangeColor : MonoBehaviour
{
[SerializeField] private VRInteractiveItem m_InteractiveItem;
public bool isGazeOver;
private void OnEnable()
{
m_InteractiveItem.OnOver += HandleOver;
m_InteractiveItem.OnOut += HandleOut;
}
private void OnDisable()
{
m_InteractiveItem.OnOver -= HandleOver;
m_InteractiveItem.OnOut -= HandleOut;
}
// 視線が当たったとき
private void HandleOver()
{
isGazeOver = true;
gameObject.GetComponent<Renderer>().material.color = Color.red;
}
// 視線が外れたとき
private void HandleOut()
{
isGazeOver = false;
gameObject.GetComponent<Renderer>().material.color = Color.white;
}
}
Editor上でVRInteractiveItemに自分自身のCubeを指定しておきます。
動作確認
Editorで起動してみると、視線が当たったときにCubeの色が変わっていることが確認できます。
この手順で、例えばどのメニューに今視線が当たってるかを判断したり出来ます。
②GearVRタッチパッドの入力を受け取る
GearVRには側面にタッチパッドが付いています。
先ほどの続きで、タッチパッドがタップされたらCubeが緑になるように改修してみます。
ChangeColor.csに以下のコードを追加します。
これで視線が当たっているときに、タップするとCubeが緑色に変化するようになります。
public class ChangeColor : MonoBehaviour
{
/*中略*/
private void OnEnable()
{
/*中略*/
m_InteractiveItem.OnClick += HandleClick;
}
private void OnDisable()
{
/*中略*/
m_InteractiveItem.OnClick -= HandleClick;
}
/*中略*/
// Clickされたとき
private void HandleClick()
{
if(isGazeOver)
{
gameObject.GetComponent<Renderer>().material.color = Color.green;
}
}
}
実行結果です。
この要領で、メニューをタップで選択する機能などが実装できると思います。
③Gear VR コントローラーを使ってみる
GearVRには別売りで専用のコントローラーがあります。
これを使うとレーザーポインターのような感覚でメニューを選んだり、コントローラーで狙ってガンシューティングしたりと操作の幅が広がります。
Oculus Utilities for Unity 5
Oculusの提供するUtilityをインポートします。
https://developer.oculus.com/downloads/package/oculus-utilities-for-unity-5/
からダウンロードします。
Main Cameraの差し替え
デフォルトのMainCameraを削除して
OVR/Prefabs/OVRCameraRig
を配置します。
コントローラーのモデル表示
RightHnadAnchorの配下に
Assets/OVR/Prefabs/GearVrController
を配置し、以下のように設定します。
動作確認
手元を見るとコントローラーが表示されていて、手首の動きに連動しているはずです。
コントローラーで指して選択する
先ほどの視線入力を応用します。
VRSampleScenes/Prefabs/Utils/MainCamera
のプレファブ内のVRCameraUIだけコピーして、RightHandAnchorの配下に配置します。
RightHandAnchorに以下のスクリプトをアタッチします。
- VRInput.cs
- Reticle.cs
- VREyeRaycaster.cs
対象のオブジェクト(Cube)を配置します。前回と同じくVRInteractive.csとChangeColor.csをアタッチします。
ビルドして実機で確認すると、こんな感じでコントローラーでCubeを指すと色が変わります。
④GearVRコントローラーのトリガーやタッチパッドの入力を受け取る
GearVRコントローラーにはトリガー、タッチパッドが付いています。
これらを利用すればモノを掴んだり、銃のトリガーを引くなど面白い操作が可能になります。
これらの入力を扱いやすくするスクリプトを用意してみました。
(Unity公式のVRInput.csを参考にしています)
using System;
using UnityEngine;
public class GearVRInput : MonoBehaviour
{
public event Action OnTriggerDown;
public event Action OnTriggerUp;
public event Action OnSwipeUp;
public event Action OnSwipeDown;
public event Action OnSwipeLeft;
public event Action OnSwipeRight;
public event Action OnTouchPadTouchDown;
public event Action OnTouchPadTouchUp;
public event Action OnTouchPadButtonDown;
public event Action OnTouchPadButtonUp;
private void Update()
{
CheckInput();
}
private void CheckInput()
{
// トリガー
if (OVRInput.GetDown(OVRInput.Button.PrimaryIndexTrigger))
{
if (OnTriggerDown != null)
OnTriggerDown();
}
if (OVRInput.GetUp(OVRInput.Button.PrimaryIndexTrigger))
{
if (OnTriggerUp != null)
OnTriggerUp();
}
// スワイプでButton.Up, Down, Left, Rightが反応するっぽい
if (OVRInput.GetDown(OVRInput.Button.Up))
{
if (OnSwipeUp != null)
OnSwipeUp();
}
if (OVRInput.GetDown(OVRInput.Button.Down))
{
if (OnSwipeDown != null)
OnSwipeDown();
}
if (OVRInput.GetDown(OVRInput.Button.Left))
{
if (OnSwipeLeft != null)
OnSwipeLeft();
}
if (OVRInput.GetDown(OVRInput.Button.Right))
{
if (OnSwipeRight != null)
OnSwipeRight();
}
// タッチパッドのタッチ
if (OVRInput.GetDown(OVRInput.Touch.PrimaryTouchpad))
{
if(OnTouchPadTouchDown != null)
OnTouchPadTouchDown();
}
if (OVRInput.GetUp(OVRInput.Touch.PrimaryTouchpad))
{
if(OnTouchPadTouchUp != null)
OnTouchPadTouchUp();
}
// タッチパッドのクリック
if (OVRInput.GetDown(OVRInput.Button.PrimaryTouchpad))
{
if(OnTouchPadButtonDown != null)
OnTouchPadButtonDown();
}
if (OVRInput.GetUp(OVRInput.Button.PrimaryTouchpad))
{
if(OnTouchPadButtonUp != null)
OnTouchPadButtonUp();
}
}
private void OnDestroy()
{
OnTriggerDown = null;
OnTriggerUp = null;
OnSwipeUp = null;
OnSwipeDown = null;
OnSwipeLeft = null;
OnSwipeRight = null;
OnTouchPadTouchDown = null;
OnTouchPadTouchUp = null;
OnTouchPadButtonDown = null;
OnTouchPadButtonUp = null;
}
}
このGearVRInput.csをCameraなど適当なオブジェクトにアタッチして、
使う側では以下のような感じで使えます。
// トリガー入力を受け取って何かする例
public class GearVRInputTest : MonoBehaviour
{
[SerializeField] GearVRInput m_GearVRInput;
private void OnEnable()
{
m_GearVRInput.OnTriggerDown += HandleTriggerDown;
}
private void OnDisable()
{
m_GearVRInput.OnTriggerDown -= HandleTriggerDown;
}
private void HandleTriggerDown()
{
Debug.Log("Trigger Down!");
}
}
以上になります。
GearVR、またその専用コントローラーを使った基本的なUI操作を実装する際の参考になれば幸いです。