第7回で触れたとおり、本稿は、執筆時点の最新版 Unity 5.3.5f1を前提としております。Unity 5.4以降では本稿にあるボタン押下機能が動作しませんので、そちらの対応については、別途、第11回でご紹介する予定です。

VRの項目選択UI

前回に続き、今回はGear VR用アプリのUIを実装します。

Oculus Homeのスクリーンショット

GearVRのコンテンツを選ぶアプリ「Oculus Home」では、回りにあるメニューを選ぶとき、視線で選んで(画面中央にあるドットに合わせて)、HMD(Head Mount Display)の側面にあるタッチパッドをタップして選択を決定します。

これが現在のGear VRの項目を選択する基本的なUIとなっています。しかし、簡単に実現する仕組みはまだ提供されておらず各アプリがそれぞれ実装しています。

VRコンテンツを作るときにメニュー項目は避けて通れません。

前回作ったButtonsをベースに、今回はこの仕組みを実装してみましょう。

完成デモは、2つのボタンのどちらかに視線を合わせた状態でタップすると、真ん中の数字が増減する、というものになります。

今回の実装の流れは次のようになります。

  • ボタンの配置
  • 視点を画面中央に描画
  • タップエリアのタップを検知して、対応ボタンの挙動を実装

素材のダウンロードと取り込み

今回は必要な素材をGitHubにアップしました。まずは、下記のリンクより素材一式(VR008-sources)をダウンロードして下さい。

 

  1. 前回のButtonsプロジェクトを開き、次画面のように、画像素材とスクリプトをプロジェクトに追加します。
  1. Assets/の直下に、Materialsというフォルダと、Scriptsというフォルダを作成します。

  2. ダウンロードした素材のうち、画像ファイル(.png)はMaterials内、スクリプトファイル(.cs)は、Scripts内に入れます。

  3. Material内のテクスチャ画像は最適なものではないので、UnityのGUIで使えるように取り込み形式を設定します。

    テクスチャを選んだ状態で右側のInspectorパネルの”Texture Type”を”Sprite (2D and UI)”に切り替え、パネル下端の”Apply”ボタンを押します。

    テクスチャの左側に三角矢印(▶)が出てきたら、変換完了です。

ボタンの配置

UIの肝となるボタンは、UnityのデフォルトのGUI(通称UGUI)を使ってボタン等を設定します。UGUIを使いこなすと、VRのUIだけではなく、一般的なアプリのようなものまで作ることができます。

しかし、その汎用性の高さと引き換えに若干設定が分かりにくく、初学者には難しい場合があります。今回は一つ一つ丁寧に説明していきます。

  1. まず、HierarchyパネルのCreateボタンを押し、出てくるメニューの中からUI/Buttonを選びます。

ここで出来上がったHierarchyを見ると、Buttonだけではなく、その上にCanvas、さらにはEventSystemというものまで追加されています。

ButtonなどUGUIのパーツは必ずCanvas内に配置される必要があり、UGUIがあるシーンにはEventSystemが必要なので、自動生成されます。

Canvasは一つのシーン内にまとまりの単位で複数保持することができますが、EventSystemは共有するのでシーン内には一つしか作れません。

  1. ボタンを配置するCanvasは、カメラの向きなどとは関係なくWorld座標内に配置するので、名前を”WorldCanvas”とリネームし、設定を進めていきます。

“WorldCanvas”を選択した状態でInspectorパネルを見るとさまざまなコンポーネントがありますが、まず”Canvas”を設定します。

  1. 最初に”Render Mode”を”World Space”にします。

  2. “Rect Transform”を次のように設定します。

    Pos X : 0, Pos Y : 0, Pos Z : 0,
    Width : 1, Height : 1,
    
  1. 次に、先ほど作ったButtonを”MinusButton”とリネームして設定します。

    Pos X : -0.2, Pos Y : 1, Pos Z : 0.6,
    Width : 0.3, Height : 0.3,
    Rotation Y : -30,
    
  2. ボタンの画像は”MinusButton”の”Image(Script)”というコンポーネントで設定します。”Source Image”の右側にある◎ボタンをクリックして”Buttons_minus”を選びます。

  1. Hierarchy内で、もう一つButtonを作成し、下記のような設定でPlusButtonを作成します。

    Pos X : 0.2, Pos Y : 1, Pos Z : 0.6,
    Width : 0.3, Height : 0.3,
    Rotation Y : 30,
    Source Image: "Buttons_plus"
    

テキストの配置

数字を表示するために、これもUGUIの仕組みでTextを配置します。

  1. まず、HierarchyパネルのCreateボタンを押し、出てくるメニューの中からUI/Textを選びます。

  2. 生成されたTextをResultTextとリネームし、WorldCanvas直下に配置されるように調整します。

  3. Textも見栄えが良くなるようにパラメータを調整します。

    Pos X : 0, Pos Y : 1.4, Pos Z : 1,
    Width : 120, Height : 60,
    Scale X : 0.005, Scale Y : 0.005, Scale Z : 0.005,
    
  4. 「Text (Script)」コンポーネントも調整します。

    Text : 123
    Font Style : Bold
    Font Size    : 50
    Alignment : 左右中央、上下中央
    Color : 白
    

ボタン押下時の処理と数字の処理

ボタンが押された時に数字が増減する仕組みは一つのスクリプトファイルを作成し、それを適用するかたちで実装します。

  1. Scriptsフォルダ内にResultText.csというファイルを作って次のように記述します。ボタンが押された時に呼び出されるメソッド(incText(), decText())をこの中に作っておくのがポイントになります。

    using UnityEngine;
    using System.Collections;
    using UnityEngine.UI;
    
    public class ResultText : MonoBehaviour {
    
        float sum;
        Text  sumText;
    
        // Use this for initialization
        void Start () {
            sum = 0;
            sumText = this.GetComponent<Text>();
            sumText.text = "0";
        }
    
        // Update is called once per frame
        void Update () {
    
        }
    
        public void addAndUpdate( float delta ) {
            sum += delta;
            sumText.text = "" + sum;
        }
    
        public void incText() {
            this.addAndUpdate(1);
        }
    
        public void decText() {
            this.addAndUpdate(-1);
        }
    }
  2. 入力できたら、Unityに戻り、このスクリプトをHierarchyのResultTextオブジェクトに追加します。

次に、ボタンを押した時に呼び出す設定を行います。

  1. MinusButtonを選択し、Inspectorパネルの下部にある “On Click ()”という項目に注目します。ここにある「+」ボタンを押すと1行追加されます。

  2. “None (Object)”を押し、開いたウィンドウから、Scene内にあるResultTextを選択します。

  3. その右にある”No Functions”を押し、ResultText > decText() を選びます。

これで、MinusButtonが押された時に、ResultTextのdecText()メソッドが呼ばれるようになります。

同様に、PlusButtonが押された時に、ResultTextのincText()メソッドが呼ばれるよう設定します。

これでボタン回りの挙動は完了です。

視点を画面中央に描画

次は、画面真ん中に視点を表示する仕組みを作ります。

これもUGUIで作りますが、この表示は常にカメラに追随するようにするので、新しくUIのCanvasを作成し、その下層にImageを作成して配置します。

このCanvasはMain Cameraの下層に配置するので、次画面のような階層になります。

  1. Canvasは次のようにInspectorパネルで設定します。

    Pos X : 0, Pos Y : 0, Pos Z : 0.3,
    Width : 2, Height : 2,
    Render Mode : World Space
    
  2. Graphics Raycaster (Script) コンポーネントはチェックをオフにします。

  3. Canvasの下にあるImageは、RectileImageとリネームして、次のように設定します。

    Pos X : 0, Pos Y : 0, Pos Z : 0.3,
    Width : 1, Height : 1,
    Scale X : 0.02, Scale Y : 0.02, Scale Z : 0.02,
    
  4. Source Imageは、Materials内にある”Buttons_rectile” を選びます。

  5. Colorで色を設定できますので好きな色に設定します。

これで画面中央にドットが表示されるようになります。

タップエリアのタップを検知して、対応ボタンの挙動を操作

最後に、GearVR側面のタッチパッドをタップした時に、画面中央にあるボタンを押すような仕組みを実装します。

これは複雑なスクリプトが必要になりますが、開発者フォーラムでこの機能を実現するスクリプトが共有されています。

ただ、そのままでは今回の用途には合わないので、若干変更したものをGVRLookInputModule.csというファイル名で冒頭のソース一式の中に入れてあります。Scriptsフォルダの中に入れてあるGVRLookInputModuleを、HierarchyのEventSystemにドラッグして設定します。

最後に、EventSystemを選択しInspectorパネルで一点だけ設定します。

Standalone Input Module (Script)というコンポーネントが初期設定で追加されていますが、これを削除します。

仕上げ

以上で概ね完成です。しかし、中央の点がボタンに重なった時に色が変わると分かりやすいので、その設定をします。

  1. MinusButtonとPlusButtonを2つ選択した状態でInspectorパネルにあるButton(Script)コンポーネントを開きます。

  2. Normal Colorが、カーソルがボタンの外にあるときの色ですので若干暗めにします。

  3. Highlighted Colorがカーソルがあたっているときの色ですので白のままにします。

  4. Pressed Colorは押した瞬間の色ですので分かりやすく赤とか青とかにしてみます。

これでFileメニューからBuild & Runを選ぶと、ビルドが終わり実機に転送され起動準備が完了します。 問題なければ、このまま端末をGear VRに入れると無事実行できます。

基本UIができれば、あとはオリジナルコンテンツの制作に集中できますので、ぜひ上記手順を活用してください。

事例紹介

Osso VRは、外科医のために移植処置トレーニングをVRで提供しようとしています。

YouTubeから(画像クリックでYouTubeの動画に遷移)

手術は、事前に同様の症例のためのトレーニングをすることが難しく、しかしながらトレーニングが必要な分野ですので、VR向きであるといえます。

まだ現段階では、触覚フィードバックなど難しいところもありそうですが、手術の流れを把握したりするには、イメージトレーニング以上に有用でしょう。

他分野でも、新しい機材の使い方を学んだりすることにも使えそうです。

Osso VRでは、OculusのCV1等を使っているようです。

著者紹介


山田宏道 (YAMADA Hiromichi) - 株式会社トルクス 代表取締役

千葉大学工学部卒業。ゲームプログラマーを経て、2005年よりフリーランス。2012年 株式会社トルクスを設立し、コンシューマー向け、ビジネス向けを問わず、さまざまなアプリを受託開発している。

現在、VR関連技術に注力中。2016年4月より島根県奥出雲町に在住。山陰エリアでUnityやVRに興味ある方を募集しています