Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
23
Help us understand the problem. What is going on with this article?
@takahi5

GearVR x Unity - 視線や専用コントローラーで操作するサンプル

More than 3 years have passed since last update.

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
に置き換えましょう。

スクリーンショット 2017-07-15 15.10.18.png

このMainCamraには視線のターゲットとなる印や、キー入力をハンドルするスクリプトが組み込まれています。

MainCamera配下のGUIReticleが照準を示す点、UISelectionBarが照準が合っているときにギューンと増えるゲージです。
今回はゲージは必要ないので、UISelectionBarとBackgroundは無効にし、GUIReticleのImageだけ使うので有効にしておきます。

次に、Editorでの開発用にカメラをキーボードで動かせるようにしておきます。
以下のスクリプトをMainCameraにアタッチします。
これでEditorで開発中はカーソルで向いてる方向を変えることが出来ます。

EditorCameraRotation.cs
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に以下のスクリプトをアタッチします。

ChangeColor.cs
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を指定しておきます。
qiita1.png

動作確認

Editorで起動してみると、視線が当たったときにCubeの色が変わっていることが確認できます。
この手順で、例えばどのメニューに今視線が当たってるかを判断したり出来ます。

gearvr_cube.mov.gif

②GearVRタッチパッドの入力を受け取る

GearVRには側面にタッチパッドが付いています。
先ほどの続きで、タッチパッドがタップされたらCubeが緑になるように改修してみます。

ChangeColor.csに以下のコードを追加します。
これで視線が当たっているときに、タップするとCubeが緑色に変化するようになります。

ChangeColor.cs

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;
    }
  }
}

実行結果です。
この要領で、メニューをタップで選択する機能などが実装できると思います。
qiita3.mov.gif

③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
を配置します。

スクリーンショット 2017-07-15 22.13.11.png

コントローラーのモデル表示

RightHnadAnchorの配下に
Assets/OVR/Prefabs/GearVrController
を配置し、以下のように設定します。
スクリーンショット 2017-07-15 22.16.15.png

同様にLeftHandAnchorも設定します。
qiita2.png

動作確認

手元を見るとコントローラーが表示されていて、手首の動きに連動しているはずです。
gearv_controller1.mov.gif

コントローラーで指して選択する

先ほどの視線入力を応用します。

VRSampleScenes/Prefabs/Utils/MainCamera
のプレファブ内のVRCameraUIだけコピーして、RightHandAnchorの配下に配置します。

qiita3.png

RightHandAnchorに以下のスクリプトをアタッチします。
- VRInput.cs
- Reticle.cs
- VREyeRaycaster.cs

そして以下のように設定します。
スクリーンショット 2017-07-15 22.41.15.png

対象のオブジェクト(Cube)を配置します。前回と同じくVRInteractive.csとChangeColor.csをアタッチします。

ビルドして実機で確認すると、こんな感じでコントローラーでCubeを指すと色が変わります。

gearvr_controller_demo.mov.gif

④GearVRコントローラーのトリガーやタッチパッドの入力を受け取る

GearVRコントローラーにはトリガー、タッチパッドが付いています。
これらを利用すればモノを掴んだり、銃のトリガーを引くなど面白い操作が可能になります。

これらの入力を扱いやすくするスクリプトを用意してみました。
(Unity公式のVRInput.csを参考にしています)

GearVRInput.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操作を実装する際の参考になれば幸いです。

23
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
takahi5
React Native/React/Expo/Rails/ UdemyでReact Native講座やってます。クーポンこちら→ https://blog.takahi5.com/udemy-coupon/
standfm
stand.fmは多くの人が音声コンテンツを気軽に発信したり、お気に入りのチャンネルを簡単に見つけられるプラットフォームを目指しています。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
23
Help us understand the problem. What is going on with this article?