Tutti Lab

元シリコンバレー在住のおっさん技術者、モバイルVRアプリ開発に挑戦中

Cardboard向けバーチャルキーボードを作ってみる

はじめに

Google Cardboardには、二種類の入力手段が用意されております。一つはGaze、画面中央に対象物が来るように首を動かすと、ゲージが現れます。ゲージがいっぱいになるまでそのままの状態を保つことで、対象物へのアクセスが可能となります。もう一つは、同じく画面中央に対象物が来るように首を動かすと照準が現れるので、その状態でボタン( Google Cardboardの右上部分、カメラのシャッターボタンのようなもの)を押下、対象物にアクセスするというものです。
いずれも首を動かして対象物の方を向く、という、VRらしい方法を前提にしております。
今回は「対象物の方向に向いてボタンを押す」入力手段を利用して、バーチャルキーボードを作ってみます。果たして「対象物の方向に向いてボタンを押す」方法で、問題なく文字入力ができるのか?その課題についても考えてみます。
f:id:tuti107:20160424043555p:plain

スクリプトの用意

Unity Assetには、有料のバーチャルキーボードのアセットが幾つかあるようですが、今回はそれらを利用せず、一からスクラッチしてみます。
利用するのは、前回ご説明したiTween、64 Flat Game Icons、あとはGoogle Cardboardです。まずはそれぞれインポートします。
次にスクリプトを作成します。今回は以下の3つのスクリプトを作成しました。

gist7e6babd903b2492c47bac7e68f74dd00

キーボード用のオブジェクトを用意

次にシーン内のオブジェクトを配置していきます。
最初に、デフォルトで配置されているMain CameraとDirectional lightを消し、Cardboard Mainを代わりに配置します。この時自動的に作成されるCardboardは不必要なので消してしまいます。ここまでは前回までと同様です。
次にキーボードに貼り付けるキーを作成します。Hierarchyにて右クリック→3D Object→Cubeを選択、名前をKeyとします。さらにそのKey上で右クリック→3D Object→3D Textを選択、名前をTextとします。これでKey配下にTextがある状態になります。Keyには、インスペクタより以下の通り設定をします。
f:id:tuti107:20160422003943p:plain
上記で作成したスクリプトKey.csをコンポーネントとして追加しText Meshに、上記でKey配下に作成したTextのText Meshをドラッグ&ドロップします(インスペクタ内のコンポーネントをドラッグ&ドロップしてもう一方のインスペクタに設定する方法は、こちらのインスペクタで関連付けを参照ください)。
Event Triggerには、Pointer Click時にKey#Push()を呼び出すように設定ください(Event Triggerについてはこちらのスケルトンをクリック可能にするを参照ください)。ここまで出来ましたら、KeyをProjectの任意のフォルダへドラッグ&ドロップし、KeyをPrefab化します(prefabについてはこちらのスケルトンをPrefab化するを参照ください)。なお、KeyのPosition、Rotation、Scaleについては、Board.cs内で計算・設定されるため適当な値で良いです。
次にKey群を配置するボードを作成します。Hierarchyにてクリック→3D Object→Cubeを選択、名前をBoardとします。さらにBoard上で右クリック→3D Object→Cubeを選択、名前をDisplayとします。さらに、そのBoard上で右クリック→3D Object→3D Textで、名前をTextとします。以上で、Board-Display-Textという構成のオブジェクトが作成されました。インスペクタでの設定は以下の通りです。
f:id:tuti107:20160422005047p:plain
上記で作成したスクリプトBoard.csをコンポーネントとして追加し、Key Prefabには上記でPrefab化したKeyを設定してください。Displayは上記で作成したDisplayをドラッグ&ドロップします。
f:id:tuti107:20160422005804p:plain
上記で作成したスクリプトDisplay.csをコンポーネントとして追加し、Textには、上記KeyのText同様、Dislay配下のTextのText Meshを設定します。

イベント処理

次にイベント処理用の設定を行います。まずHierarchyにて右クリック→Create Empty、名前をGazePointerとします。次にそのGamePointer上で右クリック→2D Object→Spriteを選択してください。そのSpriteのインスペクタにて、以下の通り、Transform/Spriteの設定を行います。Modifiers_Accuracyについては64x64のものを選択してください。
f:id:tuti107:20160422010339p:plain
次にHierarchyで右クリック→UI→Event Systemを選択、インスペクタよりGaze Input Moduleを追加し、以下の通り設定します。
f:id:tuti107:20160422010627p:plain
Cursorには、上記で作成したGamePointerをドラッグ&ドロップしてください。
最後に、CardboardMain/Head/MainCameraにPhysics Raycastを追加してください。
f:id:tuti107:20160422010842p:plain
これで完成です。

一応入力は出来るけど

f:id:tuti107:20160424043703p:plain
課題を列挙してみます。

  • 押したいキーの方を向き、そのキーを画面の中心(照準部)に合わせて、シャッターボタンを押す必要があるのですが、右下の方に配置されているキーを見ている時は、Displayに表示の「これまで入力した文字列」が見えません。
  • バーチャルキーボードの表示位置は、シーンの3D空間内となります。前回のライフを追加にてライフのハートをCardboard Main/Headに配置することで常に一定位置に表示する方法をご紹介しましたが、このような方法をとることができません。照準は常に画面中央なので、それぞれのキーに照準を当てることができなくなるためです(一つのキーしか押せません)。このため、アプリケーション毎にキーボードの表示位置を工夫する必要が出てきます。
  • 高速・長文・長時間の文字入力はかなり厳しいです。首も腕もかなり疲れます(想像していたよりは、かなり素早く入力できる印象でしたが)。

まずは今回、シンプルなバーチャルキーボードの実装をしてみましたが、まだこのままでは実用に耐えない印象です。ただし、工夫次第ではVRコンテンツで広く活用できるバーチャルキーボードへの進化も可能かな?と可能性は感じました。