tks_yoshinagaの日記

KinectやLeap motion, VRやARなどの技術を使ってやったことのメモとか

MetaQuestでUnityのUI操作

0. 本記事の内容

Meta QuestでUnityのUIを操作する例としてボタン操作の方法を紹介します。本記事ではまず手やコントローラがボタンと相互作用できることを確認し、そのあとインタラクションの一例としてボタンを押したタイミングでCubeを消す方法を解説します。
GitHubで公開しているサンプルの04-UiInteractionまたは04-UiInteraction-ARシーンでも動作を確認できます。

*この動画はAR版ですがAR/VR両対応です。

 

なお本記事は下記で作成したVRまたはARのシーンで表示している立方体を操作することを前提としています。立方体に特別なコンポーネントを追加せずQuestで眺めるだけの状態からのスタートとなりますので、他のプロジェクトでも同様の状況であれば本記事と続きの記事の内容を実践することでオブジェクト操作を実現できます。(OVRCameraRigではなくOVRCameraRigInteractionプレハブの使用を前提としています)

[VR版]

[AR版]

 

1. シーンを複製

上記の記事で作成したシーンを編集することも可能ですが、これを壊さずにオブジェクト操作を試すためシーンを複製します。不要な場合は読み飛ばしてください。

  • 前回までに作成したVR版またはAR版のシーンを開く
  • File -> Save As... をクリックして現在のシーンを新しい名前で保存
    *本記事ではUiInteractionとします
  • Hierarchyに表示されるシーン名がUiInteractionになっていることを確認

 

2. UIの作成

ボタンを作成し、3次元空間に配置します。

  • Hierarchyの空白を右クリック
  • UI -> Button - TextMeshProをクリック
  • TMP Importer(Text Mesh Proのインストーラー)が表示されたらImport TMP Essentialsをクリック
  • TMP Importerを閉じる
  • CanvasとEventSystemが追加されていることを確認

     

  • Canvasを選択しInspectorでCanvasを見つける
  • Render ModeをWorld Spaceに変更
    * UIはデフォルトでは画面上に配置されますが、この変更により3D空間に配置されるようになります
  • CanvasのInspectorのパラメータを操作してUIのサイズを下記のように調整
    PosX: 0  Pos Y: 1.2  Pos Z: 0.8
    Width: 200  Height: 90
    Scale x/y/x: 0.003
    *図中の白い枠がCanvasのエリアを表しています。

     

 

3. UIをQuestとのインタラクションに対応させる

現段階ではUIを作っただけで、Meta Questで使用するコントローラや手とのインタラクションができないため、インタラクションを実現するための設定を行います。

  • Canvasをクリックし、Inspector下方のAdd Componentをクリック
  • Pointableで検索し、候補に表示されるPointable Canvasをクリックして追加
  • 追加されたPointable CanvasCanvasの右のエリアにHierarchy内のCanvasオブジェクトをドラッグ&ドロップ

     

  • HierarchyでEventSystemを選択
  • InspectorでStandard Input ModuleのチェックをOFF
  • Add Componentをクリックし、Pointable Canvasで検索
  • Pointable Canvas Moduleをクリックして追加
    *通常の入力ではなくMetaが提供するPointable Canvasへの入力を使用

ここまでの操作はCanvasを手やコントローラでポインティング可能にするための準備になります。しかこれだけでUIとのインタラクションは実現できず、Meta XR SDKではUI(Canvas)平面の3次元空間での位置やサイズを別途、以下の方法で指定する必要があります。

  • Hierarchyの何もない空白を右クリックしCreateEmptyをクリック
  • これによって生成されたGameObjectの名前をSurfaceとする
    *名前は何でもOK
  • SurfaceをクリックしてTransformに注目
  • Surfaceオブジェクトの位置とサイズをCanvasと同じにする
    Position   X: 0   Y: 1.2   Z: 0.8
    Scale X: 0.6   Y: 0,27   Z: 1
    *ScaleはCanvasのWidth x Scale(x),  Heitht x Scale(Y)で算出。Zは何でもOK。
    *Canvasに対して多少大きくしたり小さくしたりしてもOK
  • SurfaceのInspectorのAdd Componentをクリック
  • Plane Surfaceで検索し、Plane Surfaceをクリックして追加
    *これによってSurfaceの位置(=Canvasの位置)の平面がコントローラや手のポインタと接触する準備が整う。ただし無限遠の平面なので使いにくいのでクリッピングが必要。
  • SurfaceのInspectorのAdd Componentをクリック
  • 候補からClipped Plane Surfaceをクリックして追加
    *これを用いることで、後述するクリッピング領域でのみポインタとの接触判定が行われる
  • SurfaceのInspectorのAdd Componentをクリック
  • Boundsで検索しBounds Clipperをクリックして追加
    *クリッピング領域を設定するスクリプトが追加される
  • Clipped Plane SurfaceのPlane SurfaceSurfaceオブジェクトをドラッグ&ドロップ
    *Surfaceオブジェクトの平面に対してクリッピングを適用するの意
  • Clipped Plane SurfaceのClippersを開き + ボタンをクリック
  • Element 0にSurfaceオブジェクトをドラッグ&ドロップ
    *Bounds Clipperで設定した領域でクリッピングするの意
    *Bounds ClipperのSizeが 1 1 1となっているがTransformのScaleに対する係数と考える
    *TransformのScaleを 1 1 1としてSize 0.6 0.27 1と手入力しても同じ結果になる

     

 

3. 遠隔/近接インタラクション

ここまでの操作でCanvasやその子要素のボタンをQuestとのインタラクションに対応させる準備が整いました。しかしUIがコントローラや手から出るRayに反応するか、近くで直接UIに触れるPoke操作に反応するかについての設定を行っていないため、まだボタンを操作できません。

そこでRayを使った操作とPokeを使った操作、それぞれに対応させる方法を解説します。どちらか一方でも両方設定してもOKです。

[Rayを使った遠隔操作]

  • Canvasをクリックし、Inspector下方のAdd Componentをクリック
  • Ray Interactableで検索し、候補に表示されるRay Interactableを追加
  • 追加されたRay InteractableのPointable ElementCanvasオブジェクトをドラッグ&ドロップ
    *Rayでの操作とPointable CanvasをリンクさせてCanvas内のUI操作を可能にする
  • Ray InteractableのSurfaceSurfaceオブジェクトををドラッグ&ドロップ
  • 以下のダイアログが表示されたらClippedPlaneSurfaceを選択
    *Clipped Plane Surfaceで設定された領域のみでインタラクションを可能にする

 

[Pokeを使った近接操作]

  • Canvasをクリックし、Inspector下方のAdd Componentをクリック
  • Poke Interactableで検索し、候補に表示されるPoke Interactableを追加
  • 追加されたPoke InteractableのPointable ElementCanvasオブジェクトをドラッグ&ドロップ
    *Pokeでの操作とPointable CanvasをリンクさせてCanvas内のUI操作を可能にする
  • Poke InteractableのSurfaceSurfaceオブジェクトををドラッグ&ドロップ
  • 以下のダイアログが表示されたらClippedPlaneSurfaceを選択
    *Clipped Plane Surfaceで設定された領域のみでインタラクションを可能にする

     

 

ここまでの操作でボタンとのインタラクションが可能になります。動作確認をすると以下の動画のようにボタンをクリックしたタイミングでボタンの色が少し変わっていることが確認できます。

 

4. ボタンを押したときの挙動

ここでの設定はMeta XR SDKに特化したものではなくUnityの一般的なUIの挙動に関するものです。ここでは一例として、ボタンを押したタイミングでCubeを消してみましょう。

  • Buttonをクリックし、InspectorでOn Clickを見つける
  • 右下の + ボタンをクリック
  • 新たに追加された領域のNoneと書かれた箇所にCubeをドラッグ&ドロップ
  • No Functionと書かれたドロップダウンメニューを開く
  • GameObject -> SetActiveをクリック
  • チェックボックスがOFFになっていることを確認
    *これによってボタン押下時にCubeが非アクティブになります

動作確認をすると以下の動画のようにRayでもPokeでもボタンをクリックしたタイミングCubeが消えます。

 

5. Meta XR SDKに関する記事一覧はこちら