604.3K Views
July 07, 24
スライド概要
Meta XR SDK V66-71を利用する方法です。
内容
1.環境構築
2.Building Blockの利用
3.Building Blockでパススルーを設定する
4.手とコントローラーをPrefabから組み立てる
5.Interaction sdkを使う
6.Interaction SDKを自分で組み立てる
7.手とコントローラにつかむ設定を入れる
8.つかまれる側の設定
9.Hand Poseの作り方
10.反対側の手のポーズの作り方
11.遠くの物(GameObject)を選択する
12.Pokeでボタン操作
13.Direct touch UIの作成
14.Curved UIの作成
15.Meta Horizon OS UI Setの利用
16.Shape Recognizer
17.ControllerHandsの使い方
18.Passthroughをオリジナルのシーンに組み込む
19.Passthroughを動的に切り替える
20.シーンモデルの利用
21.MRUK(MR Utility Kit)を自分で組み立てる
22.Depth APIを試す
23.Depth APIを自分のUnity Projectに組み込む
24.スペーシャルアンカーによる位置合わせ
25.共有スペーシャルアンカーのサンプル実行
26.コロケーションディスカバリー
27.同じ空間で複数人がコラボレーション
28.手とコントローラーのマルチモーダル(同時利用)
29.XR Audioを試す
30.コントローラーで移動
31.コントローラーでワープ移動
32.音に合わせてコントローラーを振動させる
33.現実のキーボードを仮想空間に表示させる
34.ワイドモーションモード(WMM)を利用する
35.OVR Metrics Toolでパフォーマンス測定
36.Questのパフォーマンス(CPU/GPUレベル)の設定
37.APPLICATION SPACEWARPでFPSを向上させる
38.MX Ink(Quest用スタイラスペン)を使う
39.実機でのDebug
40.Voice SDKで声をテキストに変える
41.やってはいけないMeta Quest
42.関連情報の紹介
想定バージョンは下記のとおり
Unity 2022.3.53f1
Meta XR SDK 71.0.0
Oculus XR Plugin 4.3.0
Meta Quest Link App 71.0.0.451.524 (旧Oculusアプリ)
META XR SDK(V66-71)でQUESTアプリ開発 XR CORE SDK + XR INTERACTION SDKの使い方 UPDATE : 2024-12-07
大久保 聡 Mail [email protected] Twitter @followapp
目次 1. 環境構築 SDKパッケージ内容 プロジェクトの設定 2. Building Blockの利用 ハンドで物をつかむ コントローラーを使う 11. 遠くの物(Game Object)を選択する 12. Poke(指でさわって)でボタン操作 13. Direct touch UI(手でさわって選ぶUI)の作成 14. Curved UIの作成 15. Meta Horizon OS UI Setの利用 3. Building Blockでパススルーを設定する 16. Controller Handsの使い方 4. ハンドとコントローラーをプレハブから組み立てる 17. 手のポーズ(ジェスチャー)を認識させる 5. Interaction SDKを使う 18. パススルーをオリジナルのシーンに組み込む 6. Interaction SDKを自分で組み立てる 19. パススルーを動的に切り替える 7. ハンドとコントローラにつかむ設定を入れる 20. シーンモデルの利用 8. つかまれる側の設定 21. MRUK(MR Utility Kit)を自分で組み立てる 9. Hand Poseの作り方 22. Depth APIを試す 10. 反対側のハンドのポーズの作り方
目次 23. Depth APIを自分のプロジェクトに組み込む 36. Questのパフォーマンス(CPU/GPU)の設定 24. スぺーシャルアンカーによる位置合わせ 37. Application SpaceWarpでFPSを向上させる 25. 共有スペーシャルアンカーのサンプル実行 38. MX Ink(Quest用スタイラスペン)を使う 26. コロケーションディスカバリー(v71) 39. 実機でのDebug 27. 同じ空間で複数人がコラボレーション 40. Voice SDKで声をテキストに変える 28. ハンドとコントローラーのマルチモーダル(同時利用) 41. ガーディアンのバウンダリー(境界)表示を消す 29. XR Audioを試す 42. やってはいけないMeta Quest 30. コントローラーでの移動 43. 関連情報の紹介 31. コントローラーでテレポート移動 32. 音に合わせてコントローラーを振動させる 33. 現実のキーボードを仮想空間に表示させる 34. ワイドモーションモード(WMM)を利用する 35. OVR Metrics Toolでパフォーマンス測定
こんなときは ハンドトラッキングやコントローラーで物をつかみたい。 1-8章 現実空間の情報を利用したい。 20-24章 つかまれた、離されたタイミングを知りたい。 8章 物をつかんだ時にそれっぽい手の形でつかみたい。 9-10章 現実の物が手前にある場合に、パススルー映像の手前に表示 したい。 22-23章 ボタンを指で押したい。 12章 手とコントローラを同時に使いたい。 28章 UIを手やコントローラーで操作したい。 13-15章 3D空間音響を使いたい。 29章 コントローラーを使うが見た目は手にしたい。 仮想空間内を移動したい。 30-31章 16章 効果音にあわせてコントローラーを振動させたい。 32章 グーチョキパーなどのジェスチャーを認識させたい。 17章 現実のキーボードを仮想空間に持ち込みたい。 33章 パススルーで現実とMR(仮想を融合)を実現したい。 18-19章 ピンク色になるのをなんとかしたい。 8章のTips VRとMRを切り替えたい。 19章
1.環境構築
動作環境 環境設定については、PluginとProject Settingsの一部を入れていますが、細かな部分は解説されて いるHomeページがたくさんありますので省略します。 プロジェクトはURPで作成しています。 検証済みのバージョンの組み合わせは下記の通りです。 Unity 2022.3.36f1 Meta XR SDK 66.0.0 Oculus XR Plugin 4.1.2 Meta Quest Link App 67.0.0.165.355 (旧Oculusアプリ) Unity 2022.3.37f1 Meta XR SDK 67.0.0 Oculus XR Plugin 4.2.0 Meta Quest Link App 68.0.0.433.361 (旧Oculusアプリ) Unity 2022.3.53f1 Meta XR SDK 71.0.0 Oculus XR Plugin 4.3.0 Meta Quest Link App 71.0.0.451.524 (旧Oculusアプリ)
V60→V62の変更点の一部 ワイド モーション モード (WMM) 手がヘッドセットの視野外にある場合でも手を追跡し、妥当な手のポーズを表示できるため、社会的存在感 とワイド モーション トラッキングが向上します。これは、内部で Inside Out Body Tracking (IOBT) を実 行し、手の追跡が失われたときに推定された手の位置を使用することによって実現されます。 Capsense コントローラーを使用するときに論理的な手のポーズを提供します。追跡されたコントローラー データを使 用して、サポートされている Oculus コントローラーに手のアニメーションとポーズの標準セットを提供し ます。一貫性を保つために、Oculus Home ハンドとコントローラーのビジュアルを提供します。 Capsense は 2 つのスタイルの手のポーズをサポートしています。 マルチモーダルがQuest3に対応 両手とコントローラーの同時利用を提供します。また、コントローラーが手元にあるかどうかも示します。 マルチモーダルにより、ユーザーは両方の世界の利点を享受できます。手を使用して没入感を実現し、コン トローラーを使用して精度と触覚を実現します。有効にすると、マルチモーダルは自動トランジションやダ ブルタップなどの他のトランジション方法をオーバーライドします。 OVRCameraRigInteractionが提供され、Interaction SDKの組み立てが楽になります。
V62→V64の変更点の一部 • IL2CPP リンク時間最適化のための新しいチェックボックス。これにより、リリース ビルドの実行時 に、生成された C# コードのリンク時間の最適化が有効になります。 • PassthroughLayerResumed _event が導入されました。このイベントは、パススルー レイヤーの レンダリングの準備が完了すると発行されます。レイヤーのアクティブ化中に発生する短い黒いフレー ムのギャップを排除するのに役立ちます。 • QuickActions に Ray Grab インタラクターを追加しました。これにより、Ray Interactor を使用し てオブジェクトを取得および変換できるようになります。 • インタラクターのレイキャストをブロックする PhysicsLayerSurface を追加しました。ブロッキン グ (または非ブロッキング) の単一のインタラクティブなレイヤーを簡単に作成できるようになります。 すべてのコライダーを手動で指定することなく、レイヤー全体をテレポート可能にしたり、ブロック テレポートを作成したりできるため、テレポート インタラクションで特に役立ちます。 • OneGrabSphereTransformer を追加して、ユーザーの周囲の球面上にオブジェクトを配置できるよ うにしました。
V64→V65の変更点の一部 • アンカー API (空間アンカー、共有アンカー、シーン アンカー) の永続性と復元力の強化。より大きな空間への拡張。 • マルチルーム サポート:マルチルーム サポートにより、既存のルームスケール アプリは機能を損なうことなくより 多くの部屋にシームレスに適応でき、ユーザーはより多くのスペースを活用してプレイ可能。 • OneGrabFreeTransformer と TwoGrabFreeTransformer は 廃止しGrabFreeTransformer に統合。 • PhysicsGrabbable は 廃止しGrabbable に統合。 • 新しい ThrowWhenUnselected コンポーネントが追加されます。 ThrowWhenUnselectedを使用すると、掴 んだオブジェクトを解放時に投げれます。
V65→V66の変更点の一部 • 「Meta XR Interaction SDK」パッケージは「Meta XR Interaction SDK Essentials」に名前が変更され、 「Meta XR Interaction SDK OVR Integration」パッケージは「Meta XR Interaction SDK」に名前が変更さ れます。 • Boundary API を使用すると、開発者は境界の可視性を抑制できるため、ユーザーは Guardian Boundary を越 えることができます。この機能はパススルーと密接に関連しています。境界の可視性は、パススルーレイヤーがレ ンダリングされている場合にのみ抑制できます。 • Meta XR Simulatorが、Unity 再生ボタンの隣に新しいボタンが表示され、Meta XR Simulatorのオンとオフを すばやく切り替えることができます。 • GrabbableがThrowWhenUnselected を自動的にアタッチするようになり、ThrowWhenUnselectedコンポー ネントはつかんだオブジェクトを離すと投げることができます。
V66→V67の変更点の一部 • Depth API の GPU 使用量 (80% 削減) と CPU 使用量 (50% 削減) が大幅に削減されたため、視覚品質が向上し、 より最適化された Depth API が実現しました。 • URP のオクルージョンに対する Shadergraph のサポート。
V67→V68の変更点の一部 • Quest 2でマルチモーダル(手とコントローラーの同時操作)が可能になりました。
•Palmメニューに新しいシェルフボタンを追加しました •Palmメニューに新しいシェルフボタンを追加しました V68→V69の変更点の一部 • Meta Quest3Sのサポート。 • Meta Horizon OS UI Setのリリース。Meta Horizon OS UI Setは、没入型エクスペリエンス向けに設計された 重要なユーザー インターフェイス コンポーネントのコレクションで、高品質なUIを簡単に構築できます。 • Palmメニューに新しいシェルフボタンを追加されました。 • HandWristOffset は、実際に使用されるアンカーであるため、HandRootOffset に名前が変更されました。手首 からのオフセットを設定する場合は、HandJoint を HandJointID.Wrist と共に使用します。
V69→V71の変更点の一部 Audio To Expressions機能は、ヘッドセットからのマイクのオーディオ ストリームを使用して、Meta の Face Tracking ブレンドシェイプまたは ARKit を使用した完全な顔のアニメーションを提供します。これにより、目や 眉毛を含む顔のアニメーションがはるかに自然になり、古い Lipsync ライブラリと比較してアプリのメモリ が削減 され、CPU の負荷も小さくできます。 Mixed Reality Utility Kit (MRUK) は、Instant Placement、Destructible Mesh、および Scene Decorator の 機能を追加します。 Instant Placement す。 : 完全なシーン検出を行わずに、Raycast を使用して UI パネルなどのオブジェクトを簡単に配置できま Destructible Mesh 提供します。 : オブジェクトやポータルを隠すメッシュを作成し、Raycast を使用してそれを破壊できる楽しい機能を Scene Decorator ことができます。 : 壁にツタや床に草を生成するなど、シーン情報でフィルター処理された複数のオブジェクトを生成する
V69→V71の変更点の一部 MSDK は、関節関連の動作情報を圧縮して送信することで体の動きを効率的にネットワーク化する方法を示し、一 般的なネットワーク プロバイダーと互換性のある新しいサンプルを github でリリースしました。 コロケーション検出機能により、Quest デバイスは近くにある他の Quest デバイスを検出し、最大 1024 バイト のデータをアドバタイズできます。コロケーション検出は、マッチメイキングのために他のデバイスを見つける方 法として使用できます。また、コロケーションを使うための共有空間アンカーの UUID を共有するためにも使用で きます。 機械学習を使用して物理環境内のキーボードを識別および追跡する、汎用追跡キーボードのサポート。 [ビルディングブロック] 新しい「カスタムマッチメイキング」ブロック
V69→V71の変更点の一部 OpenXR ハンド スケルトンのサポートが追加されました。SDK をインストールすると、新しい OpenXR スケルトンを有効にするプロンプトが表示されます。現在のハンド スケルトンは、将来のリ リースで廃止される予定です。 Dynamic Resolutionの設定が、Quest2/Proと3/3Sで設定がわかれました。
SDKの提供方法の変更 v59以降、全部入りのOculus Integrationは廃止され、個別のパッケージとして提供されるようにな ります。また全部入りは、Meta XR All-in-One SDKヘルパーパッケージとして提供されます。 Meta XR SDKは、Unity Asset Store https://assetstore.unity.com/publishers/25353 からダ ウンロード可能です。
パッケージの内容① coreを基本に必要なものを足すスタイルです。 com.meta.xr.sdk.core カメラ リグ、タッチ コントローラー、ハンド トラッキング、コンポジション レイヤー、パススルー、アンカー、 シーン管理など、Meta XR ヘッドセットが提供する多くの重要な機能が含まれています。 com.meta.xr.sdk.interaction コントローラー、⼿、およびコントローラーを⼿としてレイ、ポーク、ロコモーション、グラブなどのインタラク ションを追加します。各インタラクションはモジュール式に設計されており、単純な VR アプリケーションと複雑 な VR アプリケーションの両⽅で動作します。インタラクション SDK には、⼿固有のインタラクション、ポーズ とジェスチャの検出、ビジュアルのデバッグなど、⼿専⽤の機能もあります。 com.meta.xr.sdk.interaction.ovr.samples プレーヤー リグの OVR バリアントを使⽤した、インタラクション SDK のサンプル シーン、プレハブ、アート ア セットが含まれています。 com.meta.xr.mrutilitykit シーンクエリー、グラフィカルヘルパー、シーンデバッガーなどのユーティリティとツール群が含まれます。 com.meta.xr.sdk.audio 頭部伝達関数 (HRTF) ベースのオブジェクトやアンビソニック空間化、室内⾳響シミュレーションなどの空間オー ディオ機能を提供します。これは、Oculus Spatializer プラグインの代替品です。 com.meta.xr.sdk.voice Voice SDKを使⽤してアプリに⾳声インタラクションを導⼊し、⼈々が周囲の環境や他の⼈々と対話するためのよ り⾃然かつ柔軟な⽅法でエクスペリエンスを強化します。
パッケージの内容② ソーシャルVRアプリ用のplatformが提供されます。 com.meta.xr.simulator Meta Quest ヘッドセットと機能のシミュレーションを可能にする、開発者向けに構築された軽量の OpenXR ラ ンタイムです。ヘッドセットを頻繁に着脱する必要がなく、アプリのテストとデバッグが可能になるため、⽇々の開 発が容易になり、テスト環境のセットアップを簡素化することで⾃動化のスケールアップに役⽴ちます。 com.meta.xr.sdk.platform プラットフォーム SDKを使⽤してソーシャル VR アプリケーションを作成します。SDK の個々のコンポーネント を使⽤して、マッチメイキング、DLC、アプリ内購⼊、クラウド ストレージ、ボイス チャット、カスタム アイテ ム、実績などをエクスペリエンスに追加します。 com.meta.xr.sdk.interaction.ovr このパッケージにより、Interaction SDK が OVRPlugin と連携できるようになります。OVRPlugin または Utilities パッケージを使⽤している場合は、このパッケージを使⽤します。
提供されているASSET① パッケージ構成とほぼ内容は重複しますが、用意されているAssetのくくりは下記のようになっていま す。Core SDKとInteraction SDKが基本となるAssetです。 Meta XR Core SDK VRのコア機能、コンポーネント、スクリプト、およびプラグインをまとめたもので、UnityにおけるMeta Questアプリ開発プロセスを 容易にするとともに、その質を向上させるためのものです。Unityとのシームレスな統合が可能になるほか、さまざまなレンダリング機 能、ソーシャルやコミュニティの構築、サンプルフレームワーク、オーディオ、およびアバターの開発サポートを活用するための一連の SDKがバンドルされています。既存の Oculus Integrations パッケージ内の VR フォルダーに相当します。 Meta XR Interaction SDK Essentials (Meta XR Interaction SDK) コントローラーとハンドのインタラクションと体の姿勢検出をエクスペリエンスに追加するコンポーネントのライブラリです。このパッ ケージには、コントローラーとハンドのインタラクションと体の姿勢検出に使用される Interaction SDK に固有のコンポーネントが含 まれています。このパッケージは、既存の Oculus Integrations パッケージ内の Interaction フォルダーに相当します。 Meta XR Interaction SDK (Meta XR Interaction SDK OVR Integration) Interaction SDK が OVRPlugin と連携できるようになります。OVRPlugin または Utilities パッケージを使用している場合は、この パッケージを使用します。コントローラーとハンドのインタラクションと体の姿勢検出をエクスペリエンスに追加するコンポーネントの ライブラリです。このパッケージには、コントローラーとハンドのインタラクションと体の姿勢検出に使用される Interaction SDK に 固有のコンポーネントが含まれています。このパッケージは、既存の Oculus Integrations パッケージ内の Interaction フォルダーに 相当します。 Meta MR Utility Kit 空間認識アプリを構築するときに一般的な操作を実行するための、Scene API 上に豊富なユーティリティ/ツールのセットを提供します。 これにより、物理世界に対して迅速かつ簡単にプログラミングできるようになります。
提供されているASSET② 空間オーディオ、音声でのコマンド入力、STT(Speech to text)などの機能が含まれるAssetです。 Meta XR Audio SDK Meta XR Audio SDK には、HRTF を備えた空間オーディオ レンダラー、アンビソニック オーディオ再生、イマーシブ環境を作成 するための室内音響など、イマーシブ アプリケーション向けの包括的な空間オーディオ機能が含まれています。 このパッケージは、既存の Oculus Integrations パッケージ内の Audio フォルダーに相当します。 Meta Voice SDK - Immersive Voice Commands アプリ エクスペリエンスに音声対話を導入できます。Voice SDK を使用すると、人々がアプリを操作するためのより自然かつ柔軟な 方法で AR/VR エクスペリエンスを強化できます。たとえば、音声コマンドによりコントローラーのアクションを 1 つのフレーズで ショートカットしたり、インタラクティブな会話によりアプリをより魅力的にしたりできます。 Meta Voice SDK - Telemetry Voice SDK の依存関係であり、VoiceSDK とその関連パッケージの動作に関するインサイトを提供し、すべてのユーザーのエクスペ リエンスを向上させることができます。Voice SDK を使用する場合、テレメトリ(製品の品質向上データ)をオプトイン(利用者の許諾) またはオプトアウト(利用者が拒否)できます。 Meta Voice SDK - Composer インタラクティブな会話を設計するための Wit.ai(自然言語処理を支援する無償のサービス) の新機能である Composer のサポートを 提供します。Composer は、インテントを理解し、クライアント側のアクションをトリガーし、会話の流れに基づいて静的または動 的応答を提供できるグラフベースのダイアログ デザイナーです。 Meta Voice SDK - Dictation アプリで音声をリアルタイムで効率的にテキストに書き写すことができます。ディクテーション機能は、音声コマンドに使用するよう に設計されているのではなく、テキスト入力モダリティとして使用するように設計されています。正規表現を使用して解析し、コマン ドの処理に使用することもできますが、テキストは人間が読める形式でフォーマットされます。 Meta XR Haptics SDK 触覚クリップを Quest コントローラーで再生。ハプティック クリップを再生すると、クリップに保存されている振動パターンに従っ てコントローラーが振動します。
提供されているASSET③ 開発時に利用できるシミュレーター、XRマルチプレイ用のAsset類などです。 Meta XR Simulator Meta Quest ヘッドセットと機能のシミュレーションを可能にする、開発者向けに構築された軽量 XR ランタイムです。ヘッドセッ トを頻繁に着脱する必要がなく、アプリのテストとデバッグが可能になるため、日常の開発が容易になり、テスト環境のセットアップ を簡素化することで自動化のスケールアップに役立ちます。 Meta XR Platform SDK ソーシャル VR アプリケーションを作成します。SDK の個々のコンポーネントを使用して、マッチメイキング、DLC、アプリ内購 入、クラウド ストレージ、ボイス チャット、カスタム アイテム、実績などをエクスペリエンスに追加します。 Meta XR SDK Shared Assets Meta integration SDKsのパッケージ全体で使用される共有アセットを提供します。他の Meta サンプルおよびパッケージで使用さ れる共有アセットを提供します。このパッケージは、スタンドアロン パッケージとしてではなく、他の Meta SDK への依存関係と して取得する必要があります。 Meta XR Utilities SDK Meta XR Utilities SDKは廃止され、Meta XR Core SDKに変更されました。
提供されているASSET④ 前述のAsset①~③のAssetをまとめたものになります。インストールすると下記のように がついて るものが全部インストールされます。 Meta XR All-in-One SDK Core SDK、Interaction SDK、Voice SDK、Platform SDK などのいくつかの SDK がバンドル
ASSETの購入(無料) Unity Asset Store https://assetstore.unity.com/publishers/25353 から、購入(Add to My Assets)します。 とりあえず全部を購入しておきます。
プロジェクトの作成 本資料では、URPでプロジェクトを作成します。 テンプレートからUniversal 3Dを選択し、プロジェクトを作成を選択します。
プラットフォームの切り替え Meta Quest用にAndroid Platformに切り替えを行います。 Build Settingsをメニューから開き、Androidを選択しSwitch Platformを押下します。
プロジェクトにASSETを追加 Package Managerを開き、My Assetsから購入したMeta SDKを検索します。 V69 V71
CORE SDKのインストール Meta XR Core SDKを選択し、Installします。
TIPS:サンプルプログラム Meta XR Core SDKのサンプルプログラムはこちらからインポートできます。
INTERACTION SDK のインストール Meta XR Interaction SDKをインストールします。
V71以降の対応 OVRハンドスケルトンの廃止に伴う選択肢が表示されます。新規プロジェクトの場合、OpenXRスケ ルトンを選択します。 V71 以降、Interaction SDK では OVR ハンド スケ ルトンが廃止され、OpenXR スケルトンが採用される ようになりました。OVR スケルトンのサポートは 2025 年初頭に廃止される予定です。 新しいプロジェクトでは、OpenXR ハンド スケルトン を使用することを強くお勧めします。 アップグレードを実行すると、プレーヤー設定でスクリ プト定義 ISDK_OPENXR_HAND が設定され、 OVRRuntimeSettings の HandSkeleton バージョン が OVRHandSkeletonVersion.OpenXR に変更され ます。 既存のプロジェクトでは、2024 年末まで OVR ハンド スケルトンを引き続き使用できます。
TIPS:サンプルプログラム Meta XR Interaction SDKのサンプルプログラムはこちらからインポートできます。
TIPS : UISET EXAMPLES V69から、UISetExamplesというサンプルが追加されており、UI Setの使用方法を学ぶことができま す。
XR PLUGINのインポート Oculus XR PluginをUnity RegistryからV4.3.0をインポート。V4.1以降が表示されない場合は次 ページを参考にしてください。
TIPS : XR PLUGINのURL指定インポート Unity2022.3以降4.1以降で正式にQuest3対応されているので、 Package Managerに4.1が無い 場合はgit URLを指定してインポートしてください。
XR PLUG-IN MANAGEMENTのインストール Project Settingsを開き、XR Plug-in Managementをインストールします。 (Oculus XR Pluginをインストールした際に自動でインストールされます。)
TIPS : XR PLUG-IN MANAGEMENTがエラーの場合 4.4.1にはバグがありエラーとなる場合は、Removeして4.4.0を使ってください。
プロジェクト設定① XR Plug-in Managementの設定を行います。 PCの設定 Meta Quest (Android) の設定
プロジェクト設定② ターゲットデバイスを設定します。
OCULUS PROJECT SETUP TOOL Project SettingsのMeta XRにあるChecklistを確認し、Outstanding IssuesとRecommended Itemsを確認。WindowsプラットフォームとAndroidプラットフォームの推奨項目をチェックし対応 します。
2.BUILDING BLOCKSの利用
BUILDING BLOCKSで基本のシーン作成 メニューからBuilding Blocksを開きます。数がどんどん増えてます。
CAMERA RIGを配置する 新しいシーンを作成し、Main Cameraを削除します。 頭の部分に相当するCamera RigをドラッグアンドドロップでHierarchyに配置します。
原点を床位置に設定 Camera Rigを選択し、OVR ManagerのOrigin TypeをFloor Level(デフォルト)に設定します。
HAND TRACKINGを配置する 手に相当するHand TrackingをドラッグアンドドロップでHierarchyに配置します。
VIRTUAL HANDSを配置する Virtual HandsをドラッグアンドドロップでHierarchyに配置します。
ハンドでつかめるアイテムを配置する ハンドでつかめるアイテム、Grab InteractionをドラッグアンドドロップでHierarchyに配置します。 シーン上でCubeを、つかみやすい位置に移動させます。
QUEST LINKでPCに接続し実行 USBケーブル(Air Link)でパソコンにQuestを接続します。 UnityのPlayボタンを押下し実行します。ハンドトラッキングで手が表示され、Cubeオブジェクトが 手でつかむことが確認できます。
コントローラーを使う場合 コントローラに相当するController TrackingをドラッグアンドドロップでHierarchyに配置します。
3.BUILDING BLOCKでパススルーを設定する BUILDING BLOCKSを使う場合
CAMERA RIGを配置する 新しいシーンを作成し、Main Cameraを削除します。 頭の部分に相当するCamera RigをドラッグアンドドロップでHierarchyに配置します。
パススルーを使う PassthroughをドラッグアンドドロップでHierarchyに配置します。
パススルーをQUEST LINK経由で利用する場合 パソコンのMeta Quest Link(旧Oculusアプリ)の設定でQuest Link経由でのパススルーにチェックを いれる必要があります。
実行して確認する ビルドする場合は、QuestをUSBケーブルで接続しBuild And Runで実機で動作確認します。 Quest Linkを利用する場合は、USBでPCに接続(もしくはAir Link)しPlayを押下します。
4.ハンドとコントローラーをプレハブから組み立てる
CORE SDKのインストール インストールがまだの場合、 Meta XR Core SDKを選択しInstallします。
ヘッドトラッキングの設定 新規にシーンを作成します。 PackagesのMeta XR Core SDKのPrefabsフォルダにある。OVRCameraRigを Hierarchy(Scene)上にドラッグアンドドロップします。これで基本の頭のトラッキングができます。 不要になったMain Cameraを削除します。
ヘッドトラッキングの設定 OVRCameraRigのOrigin TypeをFloor Levelにしておくと良いです。
TRACKING ORIGIN TYPEについて Tracking Origin Type 説明 Eye Level アプリ起動時のHMD(頭)の位置を原点(0,0,0)に設定します。目線を中心にコンテンツを構 築する際に使います。 Floor Level アプリ起動時のHMD(頭)位置のX,Z座標の真下の床を原点(0,0,0)に設定します。 床位置は、ガーディアン設定時の床位置となります。 カメラ位置が床からの頭の位置、すなわち目線の高さになるので自然です。 Stage Floor Levelと同様であるが、シーン上のOVRCameraRigの向きが正面(Z+方向)になり、リ センターが無効となります。 コンテンツの見せたい方向に、初期の視線を向けることができます。また、ヘッドセットを はずしてかぶり直したときにリセンターがかかりますが、リセンターをかけたくない場合に もこの設定が有効になります。
HMDを同じ高さに設置し、起動した際の Unity上でのカメラ位置の違い。 カメラ起動時に横を向いた場合のUnity上でのカメラ 向きの違い。 シーン上のOVR Camera Rigの向き Eye Level 横を向いて アプリを起動 Floor Level Floor Levelでは、Unity上の原点から 目線位置にカメラが移動していること がわかります。 Stage Floor Level Stageではアプリ起動時の向きに関係なく、シーン上の OVR Camera Rigの向きが初期の方向になります。
手とコントローラーのどれを使うか OVRManagerのHand Tracking Supportの設定で、手とコントローラーのどれを使うかを設定でき ます。
コントローラートラッキングの設定① PackagesのMeta XR Core SDKのPrefabsフォルダにある。OVRControllerPrefabを Hierarchy(Scene)上のLeftControllerAnchor(RightControllerAnchor)の下に、ドラッグアンドド ロップします。
コントローラートラッキングの設定② LeftControllerAnchor(RightControllerAnchor)の下のOVRControllerPrefabを選択し、 InspectorでControllerをLtouch(RTouch)に設定します。これで基本のコントローラーのトラッキン グができます。
ハンドトラッキングの設定① PackagesのMeta XR Core SDKのPrefabsフォルダにある。OVRHandPrefabを Hierarchy(Scene)上のLeftHandAnchor(RightHandAnchor)の下に、ドラッグアンドドロップし ます。
ハンドトラッキングの設定② RightHandAnchorの下のOVRHandPrefabを選択し、InspectorでHand Typeを右手に設定します。 (Skelton Type/ Mesh Typeは、自動で変更されます。) これで基本の手のトラッキングができます。 OpenXRハンドスケルトンの場合 OVRハンドスケルトンの場合
動作をEDITORで確認 Meta QuestをUSBケーブルで接続(AirLinkでも可)し、Quest Link起動。 Unity Editorで実行します。コントローラーをもって認識するか? するか確認します。 コントローラーを置いて手を認識
5.INTERACTION SDKを使う
INTERACTION SDKとは 手やコントローラーでより細かな操作を行うことができます。 ものをつかむ 遠くのものをつかむ ボタンを押す ものをつかんだ時の手の形をそれっぽく見せる 手のジャスチャーを認識させる シーン内を移動する etc.
INTERACTION SDKの使い方 1. Building Blocksを使う。 2. OVRCameraRigInteractionプレハブをベースに組み立てる。 次ページ以降に軽く、中身の解説を行っています。 3. その他の用意されているプレハブとコンポーネントをベースに組み立てる。 Interacgtion SDKを自分で組み立てる以降の章で解説を行っています。こちらを理解した上で Building Blocksや、 OVRCameraRigInteractionを使うというのが基本になるかと思います。
INTERACTION SDK のインストール インストールがまだの場合、 Meta XR Interaction SDKをインストールします。
OVR CAMERA RIG INTERACTIONの追加 新しいシーンを作成します。 Packages/Meta XR Interaction SDK/Runtime/Prefabsより、OVRCameraRigInteractionを追 加します。 不要となるMain Cameraを削除します。
OVR CAMERA RIG INTERACTIONの確認 OVRCamaraRigがあり、またInteraction SDKの機能が網羅的にセットされた構成となっています。 手とコントローラーの中身を見ていくと、つかんだり移動したりする機能が確認できます。 Poke Ray Grab Locomotion Distance Grab : 直接さわって操作 : Rayを飛ばして操作 : 直接つかむ : 移動用 : 遠くのものをつかむ
CONTROLLER INTERACTORSの設定の確認 ControllerInteractorsのInteractor Groupを確認します。Groupに配下にあるInteractorがセットさ せれているのが確認できます。使うInteractorを配下にセットし、その参照をGroupにセットするこ とでその機能が利用できるようになる仕組みです。
QUEST LINKでPCに接続し実行 USBケーブル(Air Link)でパソコンにQuestを接続します。 UnityのPlayボタンを押下し実行します。ハンドトラッキングで手が表示され、コントローラーを持つ とコントローラーが表示されます。移動に使うロコモーションのInteractorも含まれるため、移動や回 転の操作も可能です。(移動できる領域が未設定なので移動はできません。) このような感じで全部入りの手とコントローラーの設定済みのプレハブを簡単に利用できます。
必要な機能(INTERACTOR)の選択方法 コントローラーでつかみたい場合だとGrabInteractorだけを残し、他のInteractorを削除します。 GroupのElementから、削除したInteractorの参照を削除します。 Interactorの使い方は、次ページ以降個別に説明していますので、そちらを参考にしてください。
6.INTERACTION SDKを自分で組み立てる
OVR INTERACTIONを追加 OVR Interactionを自分で組み立てる場合、前セクションの「ハンドとコントローラーをプレハブから 組み立てる」の状態から作業を継続します。 Packages/Meta XR Interaction SDK/Runtime/Prefabsより、OVRInteraction追加します。
OVR INTERACTIONの設定 OVRInteractionのCameraRigにOVRCameraRigの参照を設定します。 OVRRigRefは自動でセットされます。
ハンドとコントローラーの追加 OVRInteractionの下に、PackagesよりOVRControllers、OVRHandsプレハブを追加します。
ハンドの表示をINTERACTION SDK側にまかせる Interaction側で手の表示を行う場合は、両方の手のOVRHnadPrefabの手の表示部分を削除します。 両手に 実施 削除
実行して確認する ビルドする場合は、QuestをUSBケーブルで接続しBuild And Runで実機で動作確認します。 Quest Linkを利用する場合は、USBでPCに接続(もしくはAir Link)しPlayを押下します。 コントローラーを使うと、コントローラーが表示されます。コントローラーを置いて、手をかざすとハ ンドトラッキングに切り替わり手が表示されます。
補足:手の表示をCORE SDK側にまかせる場合 Core SDKとInteraction SDK側両方で手が表示されているため、Interaction SDKの表示を消す場 合はHandVisualRight/Leftを非Activeにします。この場合「ハンドの表示をInteraction SDK側に まかせる」の作業は不要です。
7.ハンドとコントローラにつかむ設定を入れる
ものをつかむ つかむ側とつかまれる側に、必要なコンポーネントを追加して実現します。 つかまれる側 つかむ側 何でどのようにつかむか ハンド、コントローラー × Grab、Ray、Poke… + Interactor つかむ + Interactable Grabbable Transformer 何でどのようにつかまれるて、どの ように動かすか ハンド、コントローラー × Grab、Ray、Poke… × 平面上、軸、球
HANDS / CONTROLLER / CONTROLLER HANDS 3種のプレハブと、つかむ側・つかまれる側のコンポーネントを組み合わせつかみを実装します。 プレハブ名 OVRHands OVRControllers OVRControllerDrivenH ands つかむ側のコンポーネント つかまれれる側 のコンポーネント HandGrabInteractor HandGrabInteractable HandPokeInteractor PokeInteractable HandRayInteractor RayInteractable DistanceHandGrabInteractor HandGrabInteractable ControlleGrabInteractor GrabInteractable ControllerPokeInteractor PokeInteractable ControllerRayInteractor RayInteractable ControllerDistanceGrabInteractor GrabInteractable HandGrabInteractor HandGrabInteractable HandPokeInteractor PokeInteractable HandRayInteractor RayInteractable DistanceHandGrabInteractor HandGrabInteractable 入力 (手・コントローラー) 見え方
コントローラでつかむ① ControllerGrabInteractorを検索し、ControllerInteractorsの配下に追加します。
コントローラでつかむ② 両方の手のCotrollerInteractorsに、追加したInteractorの参照を設定します。 両手に 実施
ハンドでつかむ① HandGrabInteractorを検索し、HandInteractorsの配下に追加します。
ハンドでつかむ② 両方の手のHandInteractorsLeft(Right)に、追加したInteractorの参照を設定します。 両手に 実施
8.つかまれる側の設定
CUBEをつかめるように① Cubeを作成し、RigidBodyを追加します。つかみやすい位置においてください。CubeにはCollider がついていますが、独自のメッシュなどの場合は自分でColliderを追加します。 落ちないようにUse Gravity=True、Is Kinematic=Trueに設定します。
CUBEをつかめるように② Cubeに、InspectorのAdd Componentから、 GrabFreeTransformerとGrabbableコンポーネン トを追加します。 GrabbableコンポーネントにCubeにさきほどつけたGrabFreeTransformerを設定します。
CUBEをコントローラーでつかめるようにする Cubeに、Grab Interactableコンポーネントを 追加します。 Grab Interactableコンポーネントにつかみ位置 とRigidbodyが自動で設定されます。(設定され ていない場合は手動で設定します。)
CUBEをハンドでつかめるようにする Cubeに、Hand Grab Interactableコンポーネ ントを追加します。 Hand Grab Interactableコンポーネントにつか み位置とRigidbodyが自動で設定されます。(設 定されていない場合は手動で設定します。)
ハンドでもコントローラでも、コントローラーハンド(コントローラー使用で表示は手)でもつかめるよ うにするならば、Interactableを複数つければ良いです。
実行して確認する ビルドする場合は、QuestをUSBケーブルで接続しBuild And Runで実機で動作確認します。 Quest Linkを利用する場合は、USBでPCに接続(もしくはAir Link)しPlayを押下します。 手もしくはコントローラーでCubeがつかめるようになっています。
V65の変更点 One Grab Free TransformerとTwo Grab Free Transformerが、GrabFreeTransformerに統合 されています。使い方は2つのコンポーネントの代わりに、 GrabFreeTransformerを追加するだけ です。
その他のコンポーネント Grabbable 挙動 Grabbable Transformerと組み合わせてものをつかめるようになります。 Physics Grabbable(廃止予定) Grabbableに統合(V65~) Grabbableコンポーネントと併用し、物理挙動をもつものをつかめるようになり ます。Rigid Bodyは、Use Gravity=True Is Kinematic=Falseで使います。 Transformer 挙動 One Grab Free Transformer(廃止予定) Two Grab Free Transformer(廃止予定) GrabFreeTransformer (V65~) 片手持ち/両手持ち GrabFreeTransformerに統合されます。 One Grab Translate Transformer XYZの相対移動範囲を限定でき、平面上を動かしたりする場合に利用。 One Grab Physics Joint Transformer Configurable Jointを使用してターゲットを制御できる。 One Grab Rotate Transformer 回転軸を固定、回転のPivotと回転範囲を指定できる。 One Grab Sphere Transformer(V64~) 円弧上の移動範囲を指定できる。 Two Grab Plane Transformer Yの移動範囲を限定でき、平面上を動かしたりする場合に利用。 Two Grab Rotate Transformer 回転軸を固定、回転のPivotと回転範囲を指定できる。
PHYSICS GRABBABLEの例 右手から左手に渡せるようになっ たり、落下物を空中でつかむこと ができます。キャッチボールでき るということです。 ものを投げたい場合、 ThrowWhenUnselectedコン ポーネントを追加します。 ※V65以降で、Grabbableに統合 されます。 ※V66以降で、 ThrowWhenUnselectedが Grabbableをアタッチした際に 自動的に追加されます。
ONE GRAB TRANSLATE TRANSFORMERの例 移動可能範囲を設定する場合は、 Constrainにチェックをいれる。 XとZを-30cm~30cmしか移動 できないようにし、Yの移動制限 はなしの場合。
TWO GRAB FREE TRANSFORMERの例 両手で握って回転や拡大縮 小させる場合の例です。 拡大縮小に制限を設ける場 合は、 Constrainに値を設 定。
ONE GRAB SPHERE TRANSFORMERの例 Sphere Centerを中心に上 下30度の範囲に移動制限を 設ける例です。 中心からの距離による制限 はなさそうで、無限球の上 下角の移動制限をつけるこ とができます。 30度 -30度 Sphere Center 横からみた場合の移動可能範囲
TIPS:握られた、離されたタイミングのイベントをとる PointableUnityEventWrapperを追加して、Grabbableを参照として指定することでSelectと Unselectのタイミングをとることが可能です。 public class GrabEvent : MonoBehaviour { private bool isGrabbed = false; public void Select() { isGrabbed = true; } public void UnSelect() { isGrabbed = false; } }
TIPS:握られているかどうかを判定 自分が握られているかどうか、GrabInteractableのStateを参照することで判定することができます。
TIPS : 握っている物を強制的に手放す HandGrabInteractorのForceReleaseメソッドで強制手に手放すことが可能です。
TIPS:手のコライダー 手の指1本1本にコライダーを自動で付ける。Is Triggerがfalseのコライダーとなるので注意。
TIPS:ピンクのマテリアル Built-inシェーダーのマテリアルは、URPでは正常に表示されないためURP用に変換してください。 Meta XR SDKのマテリアルはPackage配下に格納されるため、Package配下のマテリアルを検索し てAssets側にコピーします。コピーしたマテリアルを選択してメニュー(Edit -> Rendering -> Convert …)から変換し、マテリアルをURP用のシェーダーに変換したマテリアルに置き換えます。
9.HAND POSEの作り方 リアルにつかんでいるように見せる
握った際に事前にきめたポーズで握る 何かの取っ手の形状に即した形でにぎらせたいなど、にぎり状態での手の形をポーズとして設定するこ とが可能です。OVRHands(手のトラッキング)を使う場合にポーズが有効となります。
POSE RECORDER 手のポーズを作成するには、Hand Grub Pose Recorderか、Hand Grab Pose Live Recorderを 使う2通りの方法があります。
ポーズを作成する前準備 mugMeshを検索し、シーン上に配置し、握れるようにGrabbableの設定を追加していきます。
左手のポーズ作成 Hand Grub Pose Recorderをメニューから開きます。 Handと握られる側のRigidBodyを設定します。
ポーズをとって記録します UnityをPlayし、 手で作りたいポーズを演じます。 狙いのポーズがとれたら、Hand Grub Pose RecorderのRecordボタンを押下します。 全部のポーズが記録できたら、Save to Collectionボタンを押下します。
コレクションを読み込む UnityのPlayを停止。 Hand Grub Pose RecorderのLoad From Collectionボタンを押下します。
手のポーズ設定 コップの取っ手の場合だと、親指と人差し指だけでつかめるように、親指と人差し指を固定し他の指は 自由に設定します。
実行して確認する ビルドする場合は、QuestをUSBケーブルで接続しBuild And Runで実機で動作確認します。 Quest Linkを利用する場合は、USBでPCに接続(もしくはAir Link)しPlayを押下します。 つかみ位置に応じて、手の設定したポーズが適用されることを確認します。
10.反対のハンドのポーズの作り方
左右の手の握りポーズを変える① HandGrabInteractableを新規につくりながら、反対の手の作り方を説明します。 Hand Grub Pose Recorderで記録したものがあれば、それをもとに反対の手を作ることも可能です。 空のGameObjectをLeftGrabInteractableという名前で作成し、HandGrabInteractableコンポー ネントを追加します。
左右の手の握りポーズを変える② HandGrabInteractableのAdd HandGrabPoseボタンを押下し、HandGrabPoseを追加します。
左右の手の握りポーズを変える③ Create Mirrored HangGrabInteractableボタンを押下。 ミラーされた右手用のGameObjectの名前を変更します。
左右の手の握りポーズを変える④ 手のポーズとにぎり位置を調整。ゴーストを操作して手のポーズも手動で変更できます。
左右の手の握りポーズを変える⑤ 親側のコンポーネントは、4つだけで良い。
11.遠くの物(GAME OBJECT)を選択する
コントローラーのRAYを使う① Meta SDKはPackages配下のためAllからControllerRayInteractorを検索し、ControllerInteractors の配下に追加します。
コントローラーのRAYを使う② 両方の手のCotrollerInteractorsに、追加したInteractorの参照を設定します。 両手に 実施
コントローラーのRAYを使う③ ControlerRayInteractor配下のTriggerSelectorで、どのボタンとRayを関連づけるかの設定が可能で す。
コントローラーのRAYを使う③ ControlerRayInteractor配下のVisualsでRayの見た目や長さの変更ができます。
ハンドのRAYを使う① Meta SDKはPackages配下のためAllからHandRayInteractorを検索し、HandInteractorsの配下 に追加します。
ハンドのRAYを使う② 両方の手のHandInteractorsLeft(Right)に、追加したInteractorの参照を設定します。 両手に 実施
ハンドのRAYを使う③ HandRayInteractor配下のVisualsでRayの見た目の変更ができます。
選択対象のオブジェクトの準備① Cubeを新たに作成し赤色に変更します。 RayInteractableとInteractableUnityEventWrapper、ColliderSurfaceコンポーネントを追加しま す。
選択対象のオブジェクトの準備② InteractableUnityEventWrapperに、追加したCubeの参照を設定します。 Collider Surfaceに、追加したCubeの参照を設定します。
選択対象のオブジェクトの準備③ RayInteractableに、追加したSurfaceの参照を設定します。
選択対象のオブジェクトの準備④ InteractableUnityEventWrapperに、 ホバー、アンホバー、セレクトイベント 発生時の処理を追加します。 Objectの参照にCubeを入れて、メッ シュレンダラーのマテリアルで、それぞ れ青、赤(もとの色)、緑をセットします。
実行して確認する ビルドする場合は、QuestをUSBケーブルで接続しBuild And Runで実機で動作確認します。 Quest Linkを利用する場合は、USBでPCに接続(もしくはAir Link)しPlayを押下します。 Rayの先にある遠くのものに対して選択を行うことができます。
UGUIを遠くから操作 「Direct touch UIの作成」の章を参照し、Poke InteractableをRay Interactableに変更すると uGUIを遠くから操作することができます。
12.POKE(指でさわって)でボタン操作 指でつついて操作する
コントローラーのPOKEを使う① Meta SDKはPackages配下のためAllからControllerPokeInteractorを検索し、ControllerInteractors の配下に追加します。
コントローラーのPOKEを使う② 両方の手のCotrollerInteractorsに、追加したInteractorの参照を設定します。 両手に 実施
ハンドのPOKEを使う① Meta SDKはPackages配下のためAllからHandPokeInteractorを検索し、HandInteractorsの配下 に追加します。
ハンドのPOKEを使う② 両方の手のHandInteractorsLeft(Right)に、追加したInteractorの参照を設定します。 両手に 実施
選択対象のオブジェクトの準備① 空のGameObjectを作成しButtonという名前に変更します。 PokeInteractableとInteractableDebugVisualコンポーネントを追加します。
補足:距離の関係 Poke Interactor(手)とPoke Interactable(操作対象)の距離に応じた、操作対象の状態 (Normal/Hover/Select/Cancel)は下記のようになっています。 Normal Hover Select Cancel Poke Enter Hover Normal Interactor (手・コントローラー) Cancel Select Normal Hover Exit Hover Normal Slect状態から多少突き抜けても Selct状態を維持する距離 一度、Hoverになると、多少はみ出ても Hover扱いにします。 Poke Interactable(操作対象)
選択対象のオブジェクトの準備② 空のGameObjectをButtonの下に作成 し名前をSurfaceに変更します。 PlaneSurface/ClippedPlaneSurface/ BoundsClipperコンポーネントを追加し ます。 Transformで向きを下向きに変更 (RotationのXを90度)します。 判定面に裏表があるので注意が必要です。 Bounds Clipperのサイズと位置をボタ ンにあわせて調整します。
選択対象のオブジェクトの準備③ ClippedPlaneSurfaceのPlane SerfaceとClippersのコンポーネントの参照をセットします。
選択対象のオブジェクトの準備④ 空のGameObjectをButtonの下に作成し名前をVisualに変更します。 VisualにPokeInteractableVisualコンポーネントを追加し、InteractableとSurfaceの参照を設定。
選択対象のオブジェクトの準備⑤ Visualの配下にCubeオブジェクトを追加します。Cubeの色を赤に変更します。 下記のようにボタンっぽい装飾を加えても良いですが、装飾部分はVisualより上の階層に配置してくだ さい。
選択対象のオブジェクトの準備⑥ VisualとCubeのPositionとScaleを下記のように設定します。
選択対象のオブジェクトの準備⑦ ButtonオブジェクトのPokeInteractableコンポーネントにClipped Plane Surfaceの参照を設定、 Interactable Debug VisualコンポーネントにMesh Rendererの参照を設定します。
選択対象のオブジェクトの準備⑧ ButtonオブジェクトのInteractableDebugVisualコンポーネントのInteractableViewとRendererに 参照を設定します。
選択対象のオブジェクトの準備⑨ 上から押すと、触れると色が青に変わり。押し込むと緑に変わります。 さらに押し込むと、指がボタンにめり込みます。
ボタンに指がめり込まないようにする① Meta SDKはPackages配下のためAllからLeftHandSyntheticとRightHandSyntheticを検索し、そ れぞれの手の下に追加します。
ボタンに指がめり込まないようにする② LeftHandSyntheticのI Modify Data From Source MonoにLeftHandの参照を設定します。 両手に 実施
ボタンに指がめり込まないようにする③ 最初に「手の表示をInteraction SDK側にまかせる」の説明を参照し、Interaction SDK側で表示し ている状態にしてください。 もとからあったVisualを非アクティブに変更します。
ボタンに指がめり込まないようにする④ PokeInteracterのHandPokeLimiterをアクティブに変更します。
ボタンに指がめり込まないようにする⑤ HandPokeLimiterに、LeftHandSyntheticの参照を設定します。 両手に 実施
TIPS:手の見た目の変更 Synthetic配下のLeftHandVisualは、Hand Debug Visualがコンポーネントとして使われており見 た目がデバッグ用となっているため、さきほど非Activeに変えたOVRLeftHandVisualをコピーして 利用すると良いです。 コピーした際には、Handの参照をSynthetic側に変更します。
実行して確認する ビルドする場合は、QuestをUSBケーブルで接続しBuild And Runで実機で動作確認します。 Quest Linkを利用する場合は、USBでPCに接続(もしくはAir Link)しPlayを押下します。 ボタンを押し込んでも、手がボタンの下に行かないように動作します。
13.DIRECT TOUCH UIの作成
DIRECT TOUCH UIとは UIを直接手やコントローラーで操作できるようにすることです。 ボタンを触って選択したり、スワイプの動きでスクロールを行うことが可能です。 Poke可能な手(コントローラー)の設定がされている状態が前提となりますので、最初に「Pokeでボタ ン操作」と同様に手やコントローラーのPokeInteractorの設定を済ませておいてください。
全体構造の作成 空のGameObjectを作成しPokeable Canvasという名前に変更します。 Pokeable Canvasの下に、空のGameObjectを作成しSurfaceという名前に変更します。 Pokeable Canvasの下に、Canvas、Panel、Buttonを作成します。
POKEABLE CANVASの作成 Pokeable Canvasを、手でタッチしやすい位置にTransformを調整します。(Canvasのサイズ調整 をしてからまた、戻って調整を行います。) Pokeable Canvasに、Poke Interactable、Pointable Canvasコンポーネントを追加します。
CANVAS(UI要素)の作成 CanvasにPlane Surfaceコンポーネント(3D空間における表面を表し、インタラクターの衝突面とな る)を追加します。CanvasのレイヤーをDefaultを選択、配下のUI要素もすべてDefaultに変更します。
SURFACEの作成 Surfaceに、Clipped Plane SurfaceとBounds Clipperコンポーネントを追加します。
POKEABLE CANVASの設定 Pokeable CanvasのInspectorを開き、参照の設定を行います。
SURFACEの設定 SurafaceのInspectorを開き、参照の設定を行います。
サイズの調整① Canvasのサイズを下記(30cm×20cm)のように設定します。Render ModeをWorld Spaceに変更 します。
サイズの調整② SurfaceのInspectorからBounds Clipperのサイズを下記(30cm×20cm)のように設定します。
POINTABLE CANVAS MODULE 空のGameObjectを作成しPointableCanvasModuleという名前に変更します。 Event SystemとPointable Canvas Modulをコンポーネントを追加します。
実行して確認する ビルドする場合は、QuestをUSBケーブルで接続しBuild And Runで実機で動作確認します。 Quest Linkを利用する場合は、USBでPCに接続(もしくはAir Link)しPlayを押下します。 ボタンに色を設定しておくと動作がわかりやすいです、手を近づけるとHighlighted Colorに変わり、 押すとPressed Colorにかわります。
14.CURVED UIの作成 UIを湾曲して配置
CURVED UIとは 3D空間上、平面で左右に広く配置すると端に行くほどゆがんで見えにくくなり、また操作上も手でさ われる範囲というものを考える必要があります。円弧にあわせてUIを配置することで、見やすく操作し やすいUIを作ることができます。Curved UIは円弧上にUIを表示するための仕組みです。 UIを画像に変換、Plane(Mesh)に変換した画像をはりつけ、 Plane(Mesh)をシリンダー形状に変形す ることで実現しています。 3次 70cm 見るだけのUI 2次 50cm タッチするUI 1次 36cm つかんで操作 ハンドメニュー
もととなるUIの作成① 空のGameObjectを作成し、名前をUI Cylinderにします。 コンポーネントにCylinderとCylinder Surfaceを追加します。Radiusが作成する円弧の半径になり、 シリンダー形状のFacingがどちらの向きに表示するかの設定です。今回は内向きになりますのでInに 設定します。(Height=0のとき無限扱い)
もととなるUIの作成② UI要素を作成します。図のようにCanvas、Panel、Buttonの階層でUIを作成します。 それぞれのサイズと位置は、下記を参考にしてください。
もととなるUIの作成③ LayerからAdd LayerでCurved UIレイヤーを作成します。 Canvasを選択し、LayerをCurved UIに変更します。子要素も全てCurved UIに変更します。
カメラの設定 UIを画像に変換して、円弧状に変形させて見せる仕組みのため、もとのUIは表示しないように OVR CameraRigの3つ(Center/Left/Right)のCameraでCulling Maskのチェックを外しCurved UIを表 示しないように設定します。
UIを画像に変換する設定 Canvasの配置をWorld Spaceに変更し、Event CameraをOVR CameraRigのCenterEyeAnchor を設定します。Gammaにチェックをいれます。 CanvasにCanvas Render Textureを追加します。Auto-Fixが表示されたらボタンを押下して、修 正を行ってください。 Pixels Per Unitを今回は1000に修正します。UIを画像かする際の解像度に関わる部分です。 Rendering LayersにCurved UIレイヤーを指定します。
画像を張り付ける先のMESHの作成① UI Cylinder配下に空のGameObjectを作成し、名前をMeshにします。 Mesh配下にPlaneを追加し、UIと同じ縦横比になるようScaleを設定します。円筒に張り付けるので すが、向きはとくに関係ないようです。
画像を張り付ける先のMESHの作成② MeshにCanva Mesh Rendererと、Canva Cylinderコンポーネントを追加します。 参照を下記のように設定します。
TIPS:見やすい表示位置 表示位置は少しさげる。円弧は頭より少し後ろを原点にしてカーブをゆるくした方が自然にみえて良い そうです。 https://youtu.be/ES9jArHRFHQ?si=T8mvOAjWhx8gz_K2
実行して確認する ビルドする場合は、QuestをUSBケーブルで接続しBuild And Runで実機で動作確認します。 Quest Linkを利用する場合は、USBでPCに接続(もしくはAir Link)しPlayを押下します。 実行するとUIが、UI Cylinderを原点にシリンダー上に変形して張り付けられていることが確認できま す。
15. META HORIZON OS UI SETの利用
UI SETとは V69以降で用意されたユーザー インターフェイス コンポーネントのコレクションです。高品質なUIを 効率的に作成することができます。 ※V69ではまだ実験的な感じが否めない、今後どんどん変更が入ると思います。 ※UnityのuGUIの組み合わせなので、Unity標準のUIの仕組みの上で実現されています。 Meta XR interaction SDKのパッケージに含まれます。
UIコンポーネントの種類 コンポーネント 概要 UI Backplate ベースとなるUIの可読性をあげるための背景になる。RoundedBoxUIPropertiesにより、丸い角を 表現してします。 Buttons 通常のボタン機能とトグルボタン機能の両方をサポートします。 Animatorで押したり放したりしたときの拡大縮小や色の変化などの視覚的なフィードバックを提供 します。 Dropdown DropDownListButtonとDropDownList の2 つのサブコンポーネントで構成されており。 DropDownListButton はボタンのコレクションの表示と非表示を切り替えるトグル ボタンとして 機能します。 DropDownListButtonが押されると、DropDownList が表示されます。 Controls トグル スイッチ、チェックボックス、ラジオ ボタンを提供します。 ラジオ ボタンはグループ内での択一の選択用に設計されています。 Sliders 大小、2 つのスライダー コンポーネントが用意されています。 Text input field/Search bar テキスト入力フィールドと検索バーのコンポーネントが用意されています。 Tooltip 入力フィールドの説明用のTooltipが用意されています。 Dialogs ボタン構成が異なる 3 つのバリアントが用意されています。ダイアログは、バックプレート、ボタン、 および画像で構成されます。
UIプレハブ(コンポーネント)の場所 Packages/Meta XR Intraction SDK Essentials/Runtim Sample/Objects/UISet配下にプレハブ が用意されています。サンプルのテーマも同じフォルダ配下にあります。
UI BACKPLATE EmptyUIBackplateWithCanvasプレハブを使用します。 UIの全体的な色調を設定するテーマはここで選べます。
BUTTONS Packages/Meta XR Intraction SDK Essentials/Runtim Sample/Objects/UISet/Button配下
DROPDOWN Packages/Meta XR Intraction SDK Essentials/Runtim Sample/Objects/UISet/Dropdown配 下
CONTROLS Button配下のプレハブの組み合わせ。
SLIDERS Packages/Meta XR Intraction SDK Essentials/Runtim Sample/Objects/UISet/Slider配下
TEXT INPUT FIELD/SEARCH BAR Packages/Meta XR Intraction SDK Essentials/Runtim Sample/Objects/UISet/TextInputField 配下。
TOOLTIP Packages/Meta XR Intraction SDK Essentials/Runtim Sample/Objects/UISet/Tooltip配下
DIALOGS Packages/Meta XR Intraction SDK Essentials/Runtim Sample/Objects/UISet/Dialog配下
16-1.CONTROLLER HANDSの使い方 コントローラを使うが見た目は手にしたい
OVR CONTROLLER HANDSは非推奨 OVRControllerHandsは非推奨となり、 OVRControllerDeivenHandsに変更されますが、 OVRControllerDeivenHandsはQuest Linkで手が表示されない問題があります。 16-1.でOVRControllerHandsの設定方法。 16-2.でOVRControllerDeivenHandsの設定方法を説 明します。
CONTROLLER HANDSの設定 新規にシーンを作成し、「Interaction sdkを自分で組み立てる」の章を完了した状態を作成します。 OVRInteractionの下に、PackagesよりOVRControllerHandsプレハブを追加します。 OVRControllersを非Activeに設定します。
コントローラーハンドにINTERACTORを追加する① HandGrabInteractor/ HandPokeInteractor/ HandRayInteractorを検索し、左右の手の ContollerHandInteractorsの配下に追加します。
コントローラーハンドにINTERACTORを追加する② 両方の手のHandInteractorsLeft(Right)に、追加したInteractorの参照を設定します。 両手に 実施
FROM OVR CONTROLLER HAND DATA SOURCEの設定 OVRControllerHandDataSourceのCamera Rig RefとTracking To World Transfomerに OVRInteractionの参照をセットする。 両手に 実施
実行して確認する Ray、Poke、Grabを試せるオブジェクトを配置します。 ビルドする場合は、QuestをUSBケーブルで接続しBuild And Runで実機で動作確認します。 Quest Linkを利用する場合は、USBでPCに接続(もしくはAir Link)しPlayを押下します。 コントローラーを使って操作します。表示は手の形になっており、 Ray、Poke、Grabで操作ができ るようになっています。
16-2.CONTROLLER DRIVEN HANDSの使い方 コントローラを使うが見た目は手にしたい
CONTROLLER DRIVEN HANDSの設定 新規にシーンを作成し、「Interaction sdkを自分で組み立てる」の章を完了した状態を作成します。 OVRInteractionの下に、PackagesよりOVRControllerDrivenHands(OVRControllerHandsは廃 止)プレハブを追加します。 OVRControllersを非Activeに設定します。
コントローラーハンドにINTERACTORを追加する① HandGrabInteractor/ HandPokeInteractor/ HandRayInteractorを検索し、左右の手の HandInteractorsLeft/HandInteractorsRightの配下に追加します。
コントローラーハンドにINTERACTORを追加する② 両方の手のHandInteractorsLeft(Right)に、追加したInteractorの参照を設定します。 両手に 実施
FROM OVR CONTROLLER HAND DATA SOURCEの設定 LeftHandAnchorのLeftOVRHandの参照を、HadnDataLeftのOvr Handにセットします。 Show Stateを Alwaysに設定します。 両手に 実施
OVR HANDの設定 OVRHandPrefabのShow Stateを Alwaysに設定します。 両手に 実施
HAND POSE TYPEの変更 OVRCameraRigのOVR Managerにある、Controller Driven Hand Poses TypeをNaturalに変更 します。
実行して確認する Ray、Poke、Grabを試せるオブジェクトを配置します。 ビルドする場合は、QuestをUSBケーブルで接続しBuild And Runで実機で動作確認します。 ※Quest Linkを利用する場合は、手が表示されない問題があります。 コントローラーを使って操作します。表示は手の形になっており、 Ray、Poke、Grabで操作ができ るようになっています。
17.手のポーズを認識させる SHAPE RECOGNIZERの使い方
SHAPE RECOGNIZERとは 手のShape(ポーズ)をもとに、例えばジャンケンのグー・チョキ・パーの手の形を検出して何かアク ションをしたいような場合に使います。
SHAPE(手のポーズ) の検出 指のポーズ (参考: Pose Detection | Oculus Developers) Shape State Curl (丸め) Open 指を完全に伸ばした状態 Neutral マグカップの周りを包むような、指を少し内側に曲げた状態 Closed 指先がほとんど手の平に付くほどに指をしっかり曲げた状態 Open 指の付け根の骨を完全に伸ばして手の平に平行になっている状 態 Neutral やや曲がっている Closed ナックル関節が目いっぱい曲がっている(右図) Open 2本の指が離れている状態(図の人差し指) Closed 2本の指をしっかりくっ付けた状態(図の親指、中指、薬指) None 現在使われていない Touching 指先関節間の距離が1.5cm以内(図の人差し指) Near 指先関節間の距離が1.5cm~15cm None 指先関節間の距離が15cmを超える Flexion (屈曲) 親指の信頼 性低い Abduction (外転) 小指非対応 Opposition (対立) Curl Flexion Abduction Opposition
サンプルのシェイプ サンプルソースには、サムズアップ、サムズダウン、ジャンケン(グー・チョキ・パーなど) のいくつか のシェイプが用意されています。サンプルのシェイプがそのまま使える場合は、こちらを流用するとよ いと思います。
新規にSHAPE(手のポーズ) の作成 Projectウィンドウで、HandPosesフォルダを作成します。 作成したフォルダで右クックしShapeファイルをBunnyという名前で作成します。
SHAPE(手のポーズ) の作成 前述、指のポーズ(Curl/ Flexion/ Abduction/ Opposition)を組み合わせて、Shapeファイルを作成 します。 Bunny(チョキ)に合わせて設定したShapeを作成します。 親指曲げる 人差し指曲げない 中指曲げない 薬指曲げる 小指曲げる
作成したSHAPEをつかって判定を行う 新規にシーンを作成し、「Interaction sdkを自分で組み立てる」の章を完了した状態を作成します。 空のGameObjectを作成し、Bunnyという名前にします。
手のSHAPE状態を提供するコンポーネントの設定① OVRHandsのHandFeatureLeft/Rightに、Finger Feature State Providerを追加します。
手のSHAPE状態を提供するコンポーネントの設定② 追加したFinger Feature State Providerに、指ごとの Thresholdsを設定します。Elementを追加し指5本分の枠を 追加します。 指を親指、人差し指、中指、薬指、小指を選択し、それぞれ にデフォルトの状態判断の閾値の設定を行います。 Meta XR Interaction SDKのRuntimeにあるDefault Settingsから、デフォルトを設定します。親指と他の指の設 定が異なるので注意してください。
手のSHAPEをACTIVE STATEとして検出する① 作成したBunnyに、InspectorのAdd Componentから、Hand RefとShape Recognizer Activate State、Active State Selectorコンポーネントを追加します。
手のSHAPEをACTIVE STATEとして検出する② OVRInteractionのOVRHandsへの参照を、HandRefに設定します。
手のSHAPEをACTIVE STATEとして検出する③ HandRefへの参照を、Shape Recognizer Active StateのHandに設定します。 Shape Recognizerへの参照を、Active State Selectorに設定します。
手のSHAPEをACTIVE STATEとして検出する④ Hand Feature State Providerへの参照を、Shape Recognizer Active Stateに設定します。
手のSHAPEをACTIVE STATEとして検出する⑤ 作成していたShape、BunnyをShape RecognaizerのShapesに設定します。
SHAPEの認識を確認する シーンにCubeを作成します。CubeにSelector Debug Visualコンポーネントを追加します。 Selectorへの参照はBunnyから設定、Bunnyを認識した際にCubeの色を変えたいためCubeの RendererをRendererに設定します。
実行して確認する ビルドする場合は、QuestをUSBケーブルで接続しBuild And Runで実機で動作確認します。 Quest Linkを利用する場合は、USBでPCに接続(もしくはAir Link)しPlayを押下します。 実行し左手でチョキのShapeのポーズをとって、Cubeの色が変わるか確認します。
手の向きを検出する 手のShapeをActive Stateとして検出する以外に、手の向きをActive Stateとして検出する Transform Recognizerがあります。手のShapeと組み合わせて使うこともできます。 State Wrist Up リストを上に向ける Wrist Down リストを下に向ける Palm Up 手のひらを上向け Palm Down 手のひらを下向き Palm Towards Face 手のひらを顔に向ける Palm Away From Face 手のひらを顔の反対にむける Fingers Up 指を上にむける Fingers Down 指を下に向ける Pinch Clear 上記状態がクリアされた Wrist Up Wrist Down Palm Up Palm Down Fingers Up Fingers Down
手の向きを提供するコンポーネントの設定 手のShapeに加え、手の向きを条件として加えます。チョキのShapeかつ手が顔の方に向いたときに Activeとなるようにしてみます。 OVRHandsのHandFeatureLeft/Rightに、Transform Feature State Providerを追加します。
手の向きを検出を追加する① BunnyにTransform Recognizer Active Stateコンポーネントを追加します。
手の向きを検出を追加する② Hand Feature State Providerへの参照を、Transform Recognizer Active Stateに設定します。 HandRefへの参照を、 Transform Recognizer Active StateのHandに設定します。
手の向きを検出を追加する③ Transform Recognizer Active Stateを、手のひらが顔を方を向いたときに設定します。 デフォルトの状態判断の閾値の設定を行います。Meta XR Interaction SDKのRuntimeにある Default Settingsから、デフォルトを設定します。
手の向きを検出を追加する④ Bunnyに複数のActive Stateをまとめる、Active State Groupコンポーネントを追加します。 Active State Groupに、Shape Recognizerと Transform RecognizerのActive Stateを追加しま す。Logic Operatorを2つのStateが同時に起こった 場合にしたいため、ANDに設定します。 Active State Selectorを、追加したState Groupに 書き換えます。
実行して確認する ビルドする場合は、QuestをUSBケーブルで接続しBuild And Runで実機で動作確認します。 Quest Linkを利用する場合は、USBでPCに接続(もしくはAir Link)しPlayを押下します。 実行し左手でチョキのポーズをとってから、顔に手のひらを向けるとCubeの色が変わるか確認します。
TIPS:その他のACTIVE STATE Shape Recognizerは静的なShapeを検出するためのものでしたが、動きを認識するものもあります。 JointDeltaProviderと組み合わせて、JointVelocityActiveStateでXYZ軸の動きの速度を、 JointRotationActiveStateで回転速度を認識するものが使えます。
TIPS:ステートの連鎖を検出 Sequence、Sequence Active Stateコンポーネントを使うことで、Acrive Stateの連鎖を検出する ことができます。下記はチョキのあとに手を顔の方に向けるという流れを検出しています。 Step.1 チョキ Step.2 手のひらを顔に向ける 連鎖が成立したら2秒間状態をアク ティブにする
18.パススルーをオリジナルのシーンに組み込む 現実の映像を表示し仮想と融合するMRの機能
パススルーの設定 新規にシーンを作成し、「Interaction sdkを自分で組み立てる」の章を完了した状態を作成します。 OVRCameraRigのOVRManagerコンポーネントで、Passthrough SupportでSupportedを選択 し、Enable Passthroughにチェックをつけます。
PC側のMETA QUEST LINK(旧OCULUSアプリ)の設定 パススルーをビルドせずUnity Editor上で確認する場合、 Meta Quest Link(旧Oculusアプリ)の設定 を変更する必要があります。
OVR PASSTHROUGH LAYERの追加 OVRCameraRigにOVR Passthrough Layerコンポーネントを追加し、PlacementをUnderlayに設 定します。
CAMERAの設定 OVRCameraRig配下にあるCenterEyeAnchorのCameraコンポーネントのClear FlagsをSolid Colorに設定し、Backgroundの色を黒色、透明に設定にします。
参考:PLACEMENTについて OVR Passthrough LayerのPlacementは、表示順が下記の通りとなります。Overlayの場合は、CG が背面に回ってしまいますし、Underlayの時に背景があるとパススルーが表示されません。 パススルー (現実) CG 背景 Overlay CG 背景 パススルー (現実) Underlay
オーバーレイタイプの変更するときはこちら Placementの切り替えは、 overlayTypeを設定することで変更可能。 [SerializeField] private OVRPassthroughLayer passThroughLayer; passThroughLayer.overlayType = OVROverlay.OverlayType.None; passThroughLayer.overlayType = OVROverlay.OverlayType.Underlay; passThroughLayer.overlayType = OVROverlay.OverlayType.Overlay;
ビルドして実行 QuestをUSBケーブルで接続し、Build And Runで実機で動作確認します。 Unity Editor上で実行する場合は、オキュラスアプリのβ機能をオンにします。Quest LinkでPCに接 続しPlayを押下します。
パススルーのサンプルプログラム Oculus Integrationの中にサンプルプログラムが含まれています。面白い使い方したものもあり参考 になります。 Lighting : 懐中電灯のサンプル
19.パススルーを動的に切り替える VRとMRを切り替える
動的にパススルーオン・オフの切り替え Skybox / Fog / Postprocessingなどを利用しているProjectで、パススルーのオン・オフを切り替えま す。 isInsightPassthroughEnabledを切り替えるだけ Fogも切っておく visible = !visible; [SerializeField] private Material sky; if (visible) // パススルーの切り替え { OVRManager.instance.isInsightPassthroughEnabled = true; RenderSettings.fog = falses; } else { OVRManager.instance.isInsightPassthroughEnabled = false; RenderSettings.fog = true; }
ISINSIGHT PASSTHROUGH ENABLEの問題 isInsightPassthroughEnabledの切り替えで画面が固まる現象発生しました。その場合は textureOpacity を透明にして回避します。 visible = !visible; if (visible) { passThroughLayer.textureOpacity = 0; } else { passThroughLayer.textureOpacity = 1; }
SKYBOX利用時のパススルーの問題 Placement の表示順によりSkyboxが透けません。Skyboxのマテリアルをnullに置き換えることで回 避します。 visible = !visible; if (visible) { passThroughLayer.textureOpacity = 0; RenderSettings.skybox = sky; } else { passThroughLayer.textureOpacity = 1; RenderSettings.skybox = null; mainCamera.backgroundColor = new Color(0f, 0f, 0f, 0f); } Skybox利用時も、パススルー画面でSolidColorの影響を受けるため、黒の透明色に設定する。
POST PROCESSING利用時のパススルーの問題 Post Processing利用時にパススルーが効かなくなります。 パススルー時には、ポストプロセスを切る設定をすることで回避します。 [SerializeField] private UniversalAdditionalCameraData cameraData; if (visible) { passThroughLayer.textureOpacity = 0; RenderSettings.skybox = sky; cameraData.renderPostProcessing = true; } else { passThroughLayer.textureOpacity = 1; RenderSettings.skybox = null; mainCamera.backgroundColor = new Color(0f, 0f, 0f, 0f); cameraData.renderPostProcessing = false; }
20.シーンモデルの利用
シーンの作成 Questで設定したシーンモデル利用して、現実空間の形状に沿ったメッシュを取得するアプリを作成し ます。現実空間の壁に穴をあけたり、床にものを置いたりすることができるようになります。 新しいシーンで試します、Camera RigとBackground PassthroughをHierarchyにドラッグアンド ドロップします。
TIPS:空間地図と移動 参考文献:https://goo.gl/uFqQtk Questは動きながら現実空間を撮影します。撮影した画像間で特徴点を対応づけ、特徴を追跡し空間地 図(環境Map)を作成します。地図があることで自分の移動(=自己位置)がわかる仕組みです。 特徴点とは、イメージ内に⾒られるパターンや際⽴つ構造 のこと 撮影対象 写真① 撮影位置 カメラ移動 edge 写真③ 撮影位置 写真② 撮影位置 カメラ移動 corne r flat blob そのため • 特徴点が変わるものは難しい 透明、鏡・ガラスなどの映り込みのある素材 動くもの、照明の変化 • 特徴のない場所(もの) 白い部屋、暗所 • 大きなQuest(カメラ)の移動 前の画像の特徴とマッチングできないくらい撮影映像が変わってし まうような場合
パーミッションの設定 [BB] Camera RigをHierarchyで選択し。OVR ManagerのScene Supprtを有効にします。
OVR SCENE MANAGER(廃止予定)を追加 OVRSceneManagerを検索し、Hierarchyにドラッグアンドドロップします。 ※OVRSceneManagerは廃止されます、MRUKに移行してください。
空間の表示用プレハブの設定 HierarchyのOVRSceneManagerを選択し、InspectorでPlane/Volume Prefabを設定します。 表示用と非表示用のサンプルとなるプレハブが用意されているので、そちらを使います。 Assets/Oculus/SampleFramework/Usage/SceneManager/Prefabsから下記のように設定を行 います。 空間のメッシュを表示する場合 空間のメッシュを表示しない場合
PLANE / VOLUMEの中身 Volume Prefabの中身は、OVR Scene Anchor/OVR VolumeがついているGame Objectです。 Plane Prafabの中身は、 OVR Scene Anchor/Volume and Plane SwitcherがついているGame Objectです。どちらも1m×1m×1mのサイズでこれが基本形ですね。 Volume Plane
INVISIBLE PLANE / INVISIBLE VOLUMEの中身 プレハブの中身は、OVR Scene AnchorとColliderだけのGame Objectです。 Invisible Volume Invisible Plane
ビルドして実行 QuestをUSBケーブルで接続し、Build And Runで実機で動作確認します。 下記は、現実世界の壁にメッシュが重なって表示されている様子です。ルーム設定で定義したセマン ティックタイプ(壁やテーブルなど)ごとにシーンアンカー(PlaneまたはVolume)が設置されています。
空間表示用のメッシュのオーバーライド Prefab Overridesで指定すれば、Questで設定したセマンティックタイプごとに表示するメッシュの 見た目を変更することができます。机や、壁、ベッドなどだけ別の見た目に変更することが可能です。
セマンティックタイプを調べる 準備で結果を表示するテキストを表示するキャンバスを用意します。CammeraRigの下の CenterEyeAnchorの下にCanvasとText(TextMeshPro)を配置します。
セマンティックタイプを調べる 空のGame Objectを作成し、名前をCheckSemanticTypeとします。 C# Scriptを作成、CheckSemanticTypeとします。
セマンティックタイプを調べる
作成したCheckSemanticTypeスクリプトを開きます。
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
void Update()
{
var position = controllerTransform.position;
var rotation = controllerTransform.rotation;
public class CheckSemanticType : MonoBehaviour
{
[SerializeField]
private Transform controllerTransform;
if (Physics.Raycast(new Ray(position, rotation * Vector3.forward), out raycastHit, 15))
{
GameObject objectHit = raycastHit.transform.gameObject;
OVRSemanticClassification semanticClassification =
objectHit?.GetComponentInParent<OVRSemanticClassification>();
[SerializeField]
private TextMeshProUGUI text = null;
if (semanticClassification != null && semanticClassification.Labels?.Count > 0)
{
text.text = semanticClassification.Labels[0];
} else
{
text.text = "";
}
} else
{
text.text = "";
}
private RaycastHit raycastHit;
}
}
セマンティックタイプを調べる CheckSemanticTypeに作成したスクリプトを追加します。 Controller Transformに、右手のアンカー、作成したTextを設定します。
ビルドして実行 QuestをUSBケーブルで接続し、Build And Runで実機で動作確認します。 右コントローラーで指し示した先のセマンティックタイプが表示されます。 ※OVRSceneManagerには、Invisible Volume / Invisible Planeを指定してもらうと全体に当たり判定(Colliderが設定さ れている)があるので、差し示しやすいです。
シーンアンカーを全部取得する
シーンマネージャが正常に読み込まれた場合(SceneModelLoadedSuccessfully)に、
SemanticClassificationを探します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GetAllSceneModel : MonoBehaviour
{
[SerializeField]
private OVRSceneManager ovrSceneManager;
private void Awake()
{
ovrSceneManager.SceneModelLoadedSuccessfully += onAnchorsLoaded;
}
private void onAnchorsLoaded()
{
var classifications = FindObjectsByType<OVRSemanticClassification>(FindObjectsSortMode.None);
foreach (var classification in classifications)
{
// sceneAnchorの処理を記述
if (classification.Contains(OVRSceneManager.Classification.Floor))
{…
}
}
}
}
21.MRUKを自分で組み立てる MR UTILITY KITの基礎
MRUK(MR UTILITY KIT)とは MRアプリを楽に作るためのUtilityとToolを提供してくれるものです。 Ray Castで指示したところに何があるか調べる。 床や壁などの表面にものを置く場所を探す。 床、壁、表面上のSpawnポイントを探す。 安全な場所を指し示すため、部屋の境界線を表示。 実機にルーム設定がなくても開発できる仕組みの提供。
META MR UTILITY KIT Package Managerを開き、My Assetsから購入したMetaを検索します。 MRUK(Meta MR Utility Kit)を選択肢、インストールします。
TIPS:サンプルプログラム MRUKのサンプルプログラムはこちらからインポートできます。
パススルーの設定 新規にシーンを作成し、「パススルーをオリジナルのシーンに組み込む」の章を完了した状態を作成し ます。
MRUKの基本プレハブの設置 PackagesのMeta MR Utility KitのToolsフォルダにある。MRUKとEffectMeshを Hierarchy(Scene)上にドラッグアンドドロップします。
MRUKの設定① Sceneロード時、ルームの作成・更新・削除時のイベントに応じ、処理を呼ぶことができるように なっています。
MRUKの設定② Scene Settingsを開きます。シーンのデータソースを設定できます。 データソースにDevice With Prefab fallbackを設定します。 データソースには • Device上で設定したルームを使う。 • 事前に用意したPrefabを使う。 • Device上で設定したルームがない場合に Prefabを使う。 といった設定が可能です。 使用するPrefabは、Room Prefabsリスト で管理を行います。 Room Indexを-1にすると、Prefabが選択 された場合に、ランダムでどれかひとつが 選ばれます。
EFFECT MESHの設定① メッシュにEffectをつけるコンポーネントです、効果をつけるラベルを選択することができます。 Colliderをつけるかどうか、Meshに影を落とすかどうか、Meshにどのマテリアルを適用するかどう かなどです。
EFFECT MESHの設定② Collidersにチェックを入れると、表示するMeshに自動的にBox Colliderを生成してくれます。今回は デフォルトのままで良いです。表示する対象から、GLOBAL_MESHとINVISIBLE_WALL_FACEを 除外するため、Labelsを開きチェックを外します。
ビルドして実行 QuestをUSBケーブルで接続し、Build And Runで実機で動作確認します。 Unity Editor上で実行する場合は、オキュラスアプリのβ機能をオンにします。Quest LinkでPCに接 続しPlayを押下します。 実機上にルーム設定がない場合や、みつか らない場合。 また、実機を使わない場合にはデータソー スに指定した、Prefabが表示されます。 実機がなくても、Prefabのルームをもとに 開発をすることができます。
その他のTOOL Anchor Prefab Spawner シーンアンカーを仮想の物で置き換えるように使うことが可能で、シーンアンカーの位置にPrefabを Spawnさせます。窓のシーンアンカーを、景色を表示するPrefabに置き換えたり、床を草原の Prefabに置き換えるなどの使い方ができます。 Find Spawn Positions 特定条件にマッチする領域に、PrefabをSpawnさせることができます。机の上に何かを置くみたいな ときに使うことができます。 Room Guardian プレーヤーが近づくにつれてレンダリングされるガーディアンに似た保護メッシュを作成し、最終的に はパススルーを直接表示します。これは、シーンがパススルーを使用するのではなく完全にバーチャル であることを意図している場合、安全面で役立ちます。
ANCHOR PREFAB SPAWNER① PackagesのMeta MR Utility KitのToolsフォルダにある。AnchorPrefabSpawnerを Hierarchy(Scene)上にドラッグアンドドロップします。
ANCHOR PREFAB SPAWNER② AnchorPrefabSpawnerを選択し、Prefab To SpawnをLabelsにWindows_Frameを選択し、 PrefabにVH_WINSOWを設定すると右のようにAnchor位置に窓のモデルが表示されます。 ※VH_WINDOWは、MRUKのサンプルに含まれる Prefabです。
FIND SPAWN POSITIONS① PackagesのMeta MR Utility KitのToolsフォルダにある。FindSpawnPositionsを Hierarchy(Scene)上にドラッグアンドドロップします。
FIND SPAWN POSITIONS② Spawn Objectに、Prefabを設定します。このPrefabが置ける領域を探してSpawn Amountで指 定した最大数まで配置してくれます。LabelsとSpawn Locationsで条件を指定します。 ※TABLEの上面(On Top Of Surface)に10 個配置と設定した例。
FIND SPAWN POSITIONS③ Spawn Locations Floating 空中 Any Surface すべての面が対象 Vertical Surface 垂直面が対象 On Top Of Surface 上面が対象 Hanging Down 下面が対象
ROOM GUARDIAN① PackagesのMeta MR Utility KitのToolsフォルダにある。RoomGuardianをHierarchy(Scene)上 にドラッグアンドドロップします。
ROOM GUARDIAN② ガーディアンが見えるようにするためにプレイヤーがサーフェスからどのくらい離れる必要があるかを Guardian Distanceにメートル単位で指定します。
シーンアンカーを取得する OVRSceneManagerが廃止になるため、MRUKでRoomを取得。Room内のAnchorsを取得ように なります。 下記は、QuadとCubeをAnchorと同じサイズ・位置で表示するサンプルです。 using Meta.XR.MRUtilityKit; using System; using System.Collections; using System.Collections.Generic; using UnityEngine; public class GetRoomObjects : MonoBehaviour { public void GetRoom() { var room = MRUK.Instance.GetCurrentRoom(); var anchors = room.Anchors; foreach (var anchor in anchors) { var position = anchor.transform.position; var rotation = anchor.transform.rotation;
シーンアンカーを取得する var bounds = anchor.VolumeBounds; var rect = anchor.PlaneRect; if (bounds.HasValue) { GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube); cube.name = anchor.name; var x = position.x + bounds.Value.center.x; var y = position.y + bounds.Value.center.z; var z = position.z + bounds.Value.center.y; cube.transform.SetPositionAndRotation(new Vector3(x, y, z), rotation); cube.transform.localScale = bounds.Value.size; } else if (rect.HasValue) { GameObject quad = GameObject.CreatePrimitive(PrimitiveType.Quad); Quaternion reverse = Quaternion.Euler(0, 180, 0); quad.name = anchor.name; quad.transform.SetPositionAndRotation(position, rotation * reverse); quad.transform.localScale = new Vector3(rect.Value.width, rect.Value.height, 1f); } } } }
TIPS:スぺーシャルデータをQUEST LINKで使う Meta Quest Link(旧Oculusアプリ)の設定で、Spatial Data over Meta Quest Linkをオンにする ことでQuest Linkで空間データの利用が可能となります。
22.DEPTH APIを試す 空間の奥行情報の利用したオクルージョン
空間の奥行情報の利用 現実の空間での奥行情報を利用して、CGのオブジェクトの手前に現実のものがあった場合に、現実の ものの向こう側に隠す処理(オクルージョン)を行います。より現実と融合したオブジェクトの表示が可 能となり、MRアプリでの仮想と現実の溶け込み具合を向上させることが可能です。 深度(TOF)カメラのあるQuest3でのみ利用可能です。 パススールを使う場合GPU パフォーマンスが 17% 低く、CPU パフォーマンスが 14% 低くなりま す。Depth APIを利用するとさらにパフォーマンスが悪くなるので注意が必要です。 ※V67でパフォーマンスの低下が緩和されましたが、重い処理には変わりはありません。 https://developer.oculus.com/blog/start-developing-Meta-Quest-3-tips-performance-mixed-reality/
ソフトとハードオクルージョン エッジが目立つハードオクルージョンと、GPUパワーをより使うソフトウェアオクルージョンがあり ます。 https://github.com/oculus-samples/Unity-DepthAPI
GITからソースを取得 コマンドプロンプトを開き下記にgitコマンドでサンプルソースを取得します。 git lfs install git clone https://github.com/oculus-samples/Unity-DepthAPI
UNITYプロジェクトを開く URP版のプロジェクトを開きます。Gitで取得したソースにある下記のパスをUnityで開きます。 ¥DepthAPI¥Unity-DepthAPI¥DepthAPI-URP OcclusionTogglerシーンを開きます。
プラットフォームの切替 Androidプラットフォームを選択肢、Switch Platformボタンを押下します。
ビルドして実行 QuestをUSBケーブルで接続し、Build And Runで実機で動作確認します。Unity Editor上で実行す る場合は、オキュラスアプリのβ機能をオンにします。Quest LinkでPCに接続しPlayを押下します。 実験的機能が利用可能に設定されていない場合、確認のダイアログが表示されますのでYes, enableを 選択します。
オクルージョンモードの切替え Aボタンを押下で、オクルージョン無し、ハードウェアオクルージョン、ソフトウェアオクルージョン を切り替えできます。 左コントローラーのStartボタンを押下するともう一つのシーンに切り替わります。 オクルージョンなし ハードウェアオクルージョン ソフトウェアオクルージョン
23.DEPTH APIを自分のプロジェクトに組み込む
GITからパッケージファイルのインストール 新しいURPのUnity Projectを作成します。作成したらAndroidプラットフォームにSwitchします。 Package Managerから、Add package from git URLを選択し、下記のパッケージをインポートし ます。 https://github.com/oculus-samples/Unity-DepthAPI.git?path=/Packages/com.meta.xr.depthapi.urp
オクルージョンの組み込み方 新しいシーンで試します、Camera RigとBackground PassthroughをHierarchyにドラッグアンド ドロップします。 不要になったMain Cameraを削除します。
パーミッションの設定 OVR Managerの設定で、SceneをSupportedにして、Sceneにチェックを入れます。
DEPTH MANAGERの作成 空のGameObjectを作成し、名前をEnvironmentDepthManagerにします。 EnvironmentDepthManagerにAdd ComponetでEnvironmentDepthManagerを追加します。
OCCLUSION TYPEの設定 HierarchyのEnvironmentDepthManagerを選択し、InspectorでOcclusion Typeを指定します。
PROJECT SETUP TOOL 警告やエラーがでている場合は、内容を確認しFixします。
オクルージョン対象のオブジェクトの設定 シーン上に、手でさえぎれる位置にCubeを追加し配置します。 新規にマテリアルを作成します。作成したマテリアルのShaderをMeta/Depth/URP/Occlusion Lit を設定します。作成したCubeのマテリアルにこのマテリアルを設定します。 置き換え時のShaderの対応表 Unity Shader Depth API shader Lit Occlusion Lit Unlit Occlusion Unlit Simple Lit Occlusion Simple Lit Baked Lit Occlusion Baked Lit Particles / Unlit (/Lit / Simple Lit) Occlusion Particles / Unlit (/Lit / Simple Lit)
作成したシーンをビルドに組み込む Build Settingsを開き、ビルドに含めるシーンに作成したシーンを組み込みます。他のシーンにチェッ クが入っている場合、そのチェックを外します。
ビルドして実行 QuestをUSBケーブルで接続し、Build And Runで実機で動作確認します。Unity Editor上で実行す る場合は、オキュラスアプリのβ機能をオンにします。Quest LinkでPCに接続しPlayを押下します。
OCCLUSION用のSHADERの補足 OcclusionのShaderは、CGの手前に物があった場合に透けるというShaderです。Occlusionの Shaderの後ろに、非OcclusionのShaderを配置すると、現実空間でCGの手前に物があった場合、そ こが透明になります。下記の場合はその部分に青色が表示されます。 Occlusion NonOculusion Shader Shader Underlay パススルー
24.スペーシャルアンカーによる位置合わせ 現実の位置と仮想空間の位置をひもづける
SPATIAL ANCHORとは Questは現実空間を認識して、Spatial Map(現実空間の地図)をもっています。その地図上で頭や手が いまどのような姿勢であるかを推定することで、空間内での位置のトラッキングなどを行っています。 地図は複数作ることができ、Quest起動時にマッチングが行われ過去に作成した地図と合致すれば、そ の地図が使われるような仕組みです。 Spatial Anchorとは、その地図上の特定の場所を指し示すマーカーとなるもので、ローカルまたはク ラウド上に保存することで再利用することができます。 Spatial Mapが現実空間をもとに作られてい ることから、現実空間の特定の位置を覚えておける仕組みとも言えます。 これはMRの世界では、重要な役割を果たします。現実の机の上に時計をおいてその場所を覚えておけ ば、アプリを終了させても次回起動時に同じ場所に同じ向きで、時計を配置することができるのです。
アンカーサポートの設定 OVRCamweraRigのOVR Managerコンポーネント、Generalタブの中にあるAnchor Supportに チェックをいれます。
OVR SPATIAL ANCHORコンポーネント アンカーの作成・更新・保存・削除などのライフサイクルをカプセル化したOVRSpatialAnchorを使 います。 Game ObjectにOVRSpatialAnchorコンポーネントを追加して利用します。 Game Objectがインスタンス化されたタイミングで、Game ObjectのTransform(位置・向き)に Anchorが非同期で作成されます。
ANCHORを作る シーン上にCubeを作成し、OVR Spatial Anchorをコンポーネントとして追加します。
ANCHORの作成・失敗の判断
OVRSpatialAnchorが作成するAnchorのCreatedプロパティを監視し待つというスクリプトを
Anchorという名前で作成します。
先ほどのCubeに、Anchorスクリプトを追加します。
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
private IEnumerator Start()
{
// Createdになるまで待つ
while (_spatialAnchor && !_spatialAnchor.Created)
{
yield return null;
}
public class Anchor : MonoBehaviour
{
private OVRSpatialAnchor _spatialAnchor;
private System.Guid _uuid;
if (_spatialAnchor)
{
// 作成に成功したらuuidを保管する
_uuid = _spatialAnchor.Uuid;
Debug.Log("Success : " + _uuid);
else
{
// 作成に失敗したら自殺する
Debug.Log("Failed");
Destroy(gameObject);
}
void Awake()
{
_spatialAnchor = GetComponent<OVRSpatialAnchor>();
}
}
}
}
動作をEDITORで確認 Quest Link(Air Link)で実機とPCを接続し、Unity Editor上でプレイします。実機に接続しない場合 は必ず、アンカーの作成に失敗してしまいます。 実行するとログにSuccessが表示され、アンカーをユニークに特定するUUIDが表示されます。
ANCHORを作成・削除・保存できるようにする Anchorのライフサイクルを管理できるように実装を追加していきます。今回はアンカー1個のみを管 理するものを実装します。 作成、削除、保存ができるUIを、Direct Touch UIの説明を参考に作成します。
ANCHORの形状 設置時にAnchorの向きがわかるようなメッシュを用意します。 空のGameObjectを作成し、先ほどのUIとメッシュを子オブジェクトにした構成で配置します。
ANCHORの作成
AddComponentでOVRSpatialAnchorを追加するとAnchorが自動的に作成されます、 Createdに
なるまで待機します。
// 作成したアンカーの保持(IEnumerableなリストに保持)
private List<OVRSpatialAnchor> anchors;
// 作成したアンカーのuuidを保持
private Guid[] uuids;
private async void CreateAnchor()
{
// Anchorの作成
_message.text = " Start creating the anchor....";
// コンポーネントが既にあれば削除
if (_spatialAnchor)
{
Destroy(_spatialAnchor);
}
_spatialAnchor
= gameObject.AddComponent<OVRSpatialAnchor>();
// Anchorの作成待ち
await Wait4Completion(_spatialAnchor);
}
private async Task Wait4Completion(OVRSpatialAnchor anchor)
{
while (!_spatialAnchor || _spatialAnchor.Created)
{
// タイムアウト処理を入れる
}
if (_spatialAnchor)
{
_message.text = "アンカーが作成できました";
}
else
{
_message.text = "アンカーの作成に失敗しました";
}
}
ANCHORの削除
作成したアンカーのEraseAnchorAsyncメソッドで削除を行います。
private async void DeleteAnchor()
{
// 作られていない時は削除しない
if (!_spatialAnchor) return;
_message.text = "削除中....";
await DeleteAnchorAsync(_spatialAnchor);
private async Task DeleteAnchorAsync(OVRSpatialAnchor anchor)
{
var result = await anchor.EraseAnchorAsync();
if (result.Success)
{
_message.text = "アンカーの削除に成功しました";
}
// 保存済みのuuidのリストを初期化
uuids = Array.Empty<Guid>();
// PlayerPrefsに保持いていたuuidをクリア
PlayerPrefs.SetString(_uniqueKey, "");
// コンポーネントがあれば削除
if (_spatialAnchor)
{
Destroy(_spatialAnchor);
}
}
else
{
_message.text = "アンカーの削除に失敗しました";
}
}
ANCHORの保存
作成したアンカーのSaveAnchorsAsyncメソッドで、ローカルストレージに保存を行います。
読み込み時にアンカーのUUIDが必要になるため、UUIDをPlayerPrefsでメモとして残しておきます。
private async void SaveAnchor()
{
if (!_spatialAnchor) return;
_message.text = "保存中....";
private async Task SaveAnchorAsync()
{
// 保存するアンカーの一覧を作成
anchors.Clear();
anchors.Add(_spatialAnchor);
await SaveAnchorAsync();
}
var result = await OVRSpatialAnchor.SaveAnchorsAsync(anchors);
if (result.Success)
{
_message.text = "保存に成功しました";
// SaveしたアンカーのUUIDをPlayerPrefsに覚えておく
PlayerPrefs.SetString(_uniqueKey, _spatialAnchor.Uuid.ToString());
uuids = new Guid[1] { new Guid(_spatialAnchor.Uuid.ToString()) };
}
else
{
_message.text = "保存に失敗しました";
return;
}
}
ANCHORの読み込み①
メモしておいたUUIDをPlayerPrefsから読み込みます。
保存されたUUIDが存在した場合に、アンカーの読み込みを行います。
private void Start()
{
anchors = new();
var savedUuid = PlayerPrefs.GetString(_uniqueKey, "");
if (savedUuid != "")
{
uuids = new Guid[1] { new Guid(savedUuid) };
LoadAnchors();
}
else
{
uuids = Array.Empty<Guid>();
}
}
ANCHORの読み込み②
LoadUnboundAnchorsAsyncで保存したアンカーの読み込みを行います。
読み込んだアンカーを、ローカライズ(今の空間に復元)させるのですが、空間マッピングが不十分など
の理由でローカライズに失敗した場合、一度だけリトライする処理を加えています。
private async void LoadAnchors()
{
if (uuids.Length == 0)
{
_message.text = “アンカーが見つかりませんでした";
_isSaved = false;
return;
}
await LoadAnchorsAsync();
}
private async Task LoadAnchorsAsync()
{
List<OVRSpatialAnchor.UnboundAnchor> unboundAnchors = new();
var result = await OVRSpatialAnchor.LoadUnboundAnchorsAsync(uuids, unboundAnchors);
if (!result.Success || unboundAnchors.Count == 0)
{
return;
}
if (unboundAnchors[0].Localized)
{
// すでにローカライズが終了していた場合
_onLoadAnchor(unboundAnchors[0], true);
}
else if (!unboundAnchors[0].Localizing)
{
// 空間マッピングが不十分などの理由でローカライズに失敗している場合、再度ローカライズ
_onLoadAnchor(unboundAnchors[0], await unboundAnchors[0].LocalizeAsync());
}
}
ANCHORの読み込み③
アンバインド(未割り当て)のアンカーから、Poseを取得し位置と向きを反映させます。
アンカーのコンポーネントにアンバインドのアンカーをバインド(割り当て)します。
private void OnLocalized(OVRSpatialAnchor.UnboundAnchor unboundAnchor, bool success)
{
if (!success)
{
// アンカーが読めなかった
_message.text = "読み込みに失敗しました";
return;
}
// アンカー位置に移動し、読み取ったアンカーをコンポーネントにバインドする
var pose = unboundAnchor.Pose;
transform.SetPositionAndRotation(pose.position, pose.rotation);
// コンポーネントが既にあれば削除
if (_spatialAnchor)
{
Destroy(_spatialAnchor);
}
_spatialAnchor = gameObject.AddComponent<OVRSpatialAnchor>();
// unboundのアンカーを、追加したアンカーにバインドする
unboundAnchor.BindTo(_spatialAnchor);
_message.text = "読み込みに成功しました";
}
ボタンに処理を割り当て 起動時にアンカーの自動読み込み Create、Delete、Saveにアンカーの作成、削除、保存を割り当てます。
動作をEDITORで確認 AnchorのGame Objectをつかんで移動できるようにします。移動した位置でCreateするとその場所 にAnchorが作成されます。位置が固定しつかんで動かせなくなります。 Saveボタンを押して、移動した位置に作成されたアンカーをローカルに保存します。 アプリを終了し、再度起動します。先ほどの位置に復元されたら成功です。 Deleteボタンを押下すると、 AnchorのGame Objectをつかんで移動できるようになります。
25.共有スペーシャルアンカーのサンプル実行
UNITY-SHAREDSPATIALANCHORSサンプルの実行 コロケーションは複数人で同じ空間を共有する仕組みで、MRで複数人に現実の同じ場所に同じものを みせることができます。位置合わせにスペーシャルアンカーを利用したサンプルがGitに上がっていま すのでダウンロードして試してみます。 Unity-SharedSpatialAnchorsは、4つのケースがサンプルとして実行できます。 • Spatial Anchor Creation, Saving, Loading, and Sharing • Scene Sharing • Automatic Colocation • Passthrough Avatars
実行の手順 Unityプロジェクトの準備 gitからプロジェクトをダウンロードしUnityで開きます。 Metaのプラットフォーム機能の利用準備 共有スペーシャルアンカーはQuestログイン時に利用しているユーザー情報が必要となります。そのた め作成するアプリがUser IDを取得できるように申請を行います。 Photonの利用準備 共有スペーシャルアンカーの共有許可を行うためのUser IDの共有 共有スペーシャルアンカーのUUIDのリストの共有 マルチープレイヤーの機能を実装 これらのためにPhotonを使います。Photonを利用するための準備をします。 プロジェクトを実行して動作を確認します。
UNITYプロジェクトの準備 gitからプロジェクトをダウンロードします。 https://github.com/oculus-samples/Unity-SharedSpatialAnchors ダウンロードしたプロジェクトをUnityで開きます。
META開発者アカウント作成 Meta Quest Developer Centerで開発者の登録を行います。手順の詳細は省略します。 https://developer.oculus.com/
アプリの作成 開発者ダッシュボードを開き、アプリの登録を行います。 https://developer.oculus.com/manage/
アプリを編集 マイアプリから、作成したアプリの詳細を編集します。
組織の認証 まず最初に組織の認証が必要となるので、認証の開始ボタンを押下します。
管理者認証 自分を追加で、免許証などを使った本人確認を行います。承認まで1-2営業日かかります。
データの使用のリクエストを追加 データの使用状況の確認を選択。User IDとUser Profileのプラットフォーム機能へのアクセスをリク エストします。
データの使用のリクエストを記入 用途とアプリでの使用方法を記入し、リクエストに追加ボタンを押下します。
データの使用をリクエストの送信 追加したリクエストを送信します。
データの取り扱いに関する入力
送信確認 プライバシーポリシーの確認を行い審査の申請を送信します。数分で承認されます。
アプリIDの確認 APIを選択し、アプリIDをメモします。
UNITYでの設定 メニューから設定を開き、さきほどメモしたアプリIDを入力します。 Meta Quest用のアプリの場合、Meta Quest2/ProのApplication IDの欄に入力します。 PCで実行する場合、Meta Linkを利用する場合はOculus Rift用のアプリの申請も行い、そちらのIDを 入力します。
PHOTONアカウント作成 Photonのユーザー作成を行います。手順の詳細は省略します。 https://www.photonengine.com/ja-jp#
PHOTONのアプリを作成 Photonのダッシュボードを開き、新しくアプリを作成するを押下します。 Photonの種別はPunを選択、アプリ名を入力し作成します。
APP IDの確認 作成したアプリのApp IDの欄をクリックし、App IDを表示しメモします。
PHOTONのAPP IDの設定 Project SettingsのMeta XRタブより、RecommendedからApplyを押下します。 App Idを入力し、Record App Idを押下します。
実行して確認する1人目 空間の共有を確認するため2台のQuestを利用します。 Unityでビルドを行い、2台のQuestにアプリをインストールします。 1台目でアプリを起動します。 ※Questがネットワークに接続されている必要があります。 Anchor Sharing Demoを 選択します。 Create New Roomを選択 します。 Create New Anchorを選 択します。 Anchorを任意の位置に配置し、Anchorを共有し ます。Align to Anchorを選択し、このアンカー を基準に位置合わせを行うように指定します。
実行して確認する2人目 2台目でアプリを起動します。 Networked CubeをSpawnさせ、2台のクエストで同じ位置に共有されれば成功です。 Anchor Sharing Demoを 選択します。 Join Roomを選択し、下 に表示されるRoom名を選 択します。 Spawn Networked Cubeを選択します。この ルームに参加するユーザー すべてが見て、つかむこと ができるCubeが生成され ます。
26.コロケーションディスカバリー UUIDを同じ場所にいるQUEST間で共有
コロケーションディスカバリーとは ユーザーが Bluetooth 経由で近くのユーザーにアドバタイズ(情報を公開)することで、近くのユー ザーを検出したりできるようにする機能です。 コロケーションディスカバリーを使用すると、近くのクライアントが最大 1024 バイトのデータを受 け取ることができます。 共有スペーシャルアンカーを利用する際に、同じ空間を共有するQuest間でアンカーのUUIDを教えて あげる必要がありますが、コロケーションディスカバリーを使うことで簡単にUUIDを通知することが 可能となります。 検出はそこそこ早く動きます。ネットワークを介さずにBluetoothだけで値の受け渡し可能なため、例 えば、同一箇所にあるQuestの画面を一斉に切り替えるなどの利用も可能です。
必要条件 Meta XR SDK v71以降 対応デバイスは、Meta Quest2/Quest Pro/Quest3/Quest3Sです。 Questのユーザーが検証済み組織(※)のメンバーか、その組織のテストユーザーである。 ※検証済み組織 開発者ダッシュボードで下記のどちらかを実施 ・所属する組織が法人であること : 所属する組織を地元の当局に登録すること、そして公式の電話番号や住所を 提供する。 ・あなたが組織の正式な代表者であること : 所属する組織の電話番号またはメールアドレスに送信される認証 コードを受信する。
コロケーションディスカバリーの動作イメージ ホスト側からアドバタイズを開始し、クライアント側でそれを拾うように動作します。 ホスト (ペリフェラル)側 クライアント (セントラル)側 アドバタイズ開始 最大1024バイトのデータを共有 StartAdvertisementAsync ディスカバリー開始 StartDiscoveryAsync アドバタイズ受信 アドバタイズ停止 StopAdvertisementAsync 最大1024バイトのデータ を取得 取得した情報をもとになん らかの処理を行う。 ※中の動作は不明 Bluetooth5のアドバタイズパケットは255バイトなので CDの送信可能サイズ1024ということは、一度接続している のかもしれません。
コロケーションディスカバリーの有効化 OVRCameraRigのOVRManagerコンポーネントで、Collocation Session SupportをRequiredに 設定します。
受け渡しするデータの形 テスト用にString型を2つもつクラスを作成し、このデータを受け渡しするように作成していきます。 [System.Serializable] public class ColocationSessionData { public string room; public string uuid; }
受け渡しするデータをシリアライズ化 クラスのインスタンスをバイト配列に変換します。 public class GenericSerializer<T> { // T 型のインスタンスをバイト配列にシリアル化するメソッド public byte[] Serialize(T obj) { string json = JsonUtility.ToJson(obj); return Encoding.UTF8.GetBytes(json); } // バイト配列を T 型のインスタンスにデシリアル化するメソッド public T Deserialize(byte[] data) { string json = Encoding.UTF8.GetString(data); return JsonUtility.FromJson<T>(json); } }
ホスト(ペリフェラル)側の実装 StartAdvertisementAsyncを呼び出して、アドバタイズを開始します。開始すると StopAdvertisementAsyncを呼び出すまで、クライアント側でStartAdvertisementAsyncの引数で 渡した値を取得できることができます。 private async UniTask Advertise_Flow(ColocationSessionData colocationSessionData) { var byteArrayData = serializer.Serialize(colocationSessionData); var startAdvertisementResult = await OVRColocationSession.StartAdvertisementAsync(byteArrayData); if (startAdvertisementResult.Success) { } } private async UniTask Advertise_Stop() { var startAdvertisementResult = await OVRColocationSession.StopAdvertisementAsync(); if (startAdvertisementResult.Success) { } }
クライアント (セントラル)側の実装 ディスカバリーの開始 StartDiscoveryAsyncでディスカバリーを開始します。 発見時にコールバックされる関数を用意し登録します。 private async UniTask Discover_Start() { OVRColocationSession.ColocationSessionDiscovered += OnColocationSessionDiscovered; // starts discovering session var startDiscoveryResult = await OVRColocationSession.StartDiscoveryAsync(); if (startDiscoveryResult.Success) { } } // 発見時にコールバックされる関数 private void OnColocationSessionDiscovered(OVRColocationSession.Data data) { var colocationSessionData = serializer.Deserialize(data.Metadata); Debug.Log($"The Room is {colocationSessionData.room}"); Debug.Log($"The UUID is {colocationSessionData.uuid}"); }
クライアント (セントラル)側の実装 ディスカバリーの停止 StopDiscoveryAsyncで停止します。ディスカバリーを途中で停止する場合に使います。 private async UniTask Discover_Stop() { var startAdvertisementResult = await OVRColocationSession.StopDiscoveryAsync(); if (startAdvertisementResult.Success) { } }
実行して確認する 実機でしか確認できないため、Quest 2台にBuildしたapkをインストールします。 ソースコードは省略していますが、ボタン押下に対応し開始・停止、結果の表示を実装します。 2台のQuestでアプリを起動します。 ホスト側 アドバタイズを開始します。 クライアント側 ディスカバリーを開始します。 ホスト側で設定した値が表示できることを確認できたら成功です。
27.同じ空間で複数人がコラボレーション
複数人がコラボレーションする構成 複数人が仮想空間や仮想のオブジェクトを共有しながらコレボレーションする場合には、いくつかのタイ プがあります。 ① 複数人で仮想空間へ入る ② 複数人で、現実空間上で仮想オブジェクトの共有 ③ 現実空間と仮想空間をミックスする 現状は①をメタバースで利用しています。将来的には目的に合わせて①~③を切り替えながら日常生活を 送るようになると考えます。現実と仮想の濃度を変えながら、生活している未来では常にメタバースにい るともいえますが、その頃にはメタバースという言葉がなくなっているかも知れません。
複数人で仮想空間へ入る 複数人が現実の別々の場所からひとつの仮想空間へ入る。現実空間はまったく影響せず、仮想空間の座 標系のみが使われる。用途的にはマルチプレイヤーのVRゲームやメタバースなどで使われます。 現実 Player B Player A 仮想の場所
複数人で、現実空間上で仮想オブジェクトの共有 複数人が現実の同じ空間から、同じ座標系の空間に入る。現実の同じ場所に同じ仮想のオブジェクトを 配置し、それらを複数人が現実の同じ位置にみることができます。仮想のチェス盤を現実の机の上に置 いて、複数人でプレイするというのがわかりやすい例です。 現実 Player A Player B 現実の場所+仮想オブジェクト
現実空間と仮想空間をミックスする 現実空間では異なる場所にいても、あたかも同じ場所でコミュニケーションがとれるように、仮想と現 実がミックスする例。現実の空間と仮想オブジェクトの位置関係を重視しない場合は、現実空間のコ ピーは必要ない。 現実 現実 Player A 現実空間に Player Bのアバ ターが出現、同 じ仮想オブジェ クトを操作 Degital Twins 現実空間 を仮想化 現実の場所+仮想オブジェクト Player B 仮想空間に Player Aのアバ ターが出現、同 じ仮想オブジェ クトを操作 現実の場所のコピー+仮想オブジェクト
COLOCATION機能の実装 今回は「複数人で、現実空間上で仮想オブジェクトの共有」を、Photon Fusionを使いBuilding Blocksで実際に作成してみます。
PHOTONパッケージのインストール Unity Asset StoreでPhoton Fusionを検索し、Add to My Assetsを押下しパッケージをプロジェ クトにインストールします。
META XR SDKより必要なパッケージのインストール Core SDKとInteraction SDK、Avatars SDK、Avatars SDKのサンプルをインストールします。
PHOTONアカウント作成 Photonのユーザー作成を行います。手順の詳細は省略します。 https://www.photonengine.com/ja-jp#
PHOTONのアプリを作成 Photonのダッシュボードを開き、新しくアプリを作成するを押下します。 Photonの種別はFusionを選択、アプリ名を入力し作成します。
APP IDの確認 作成したアプリのApp IDの欄をクリックし、App IDを表示しメモします。
PHOTONの設定 Fusion Hubを開き、App IDを入力します。
複数人での情報共有の流れ ロビーからセッション(ルーム)を作成し、セッション単位でプレイヤーやネットワークオブジェクトの 情報を共有するという流れになります。これらをBuilding Blocksで実現します。 STEP 01 ロビー作成、接続 STEP 02 セッション(ルーム)作成、もしくは一覧取得 STEP 03 セッション(ルーム)を選択し接続 STEP 04 マルチプレイヤーの開始 複数人のプレイヤーを引き合わ せる部分をマッチメイキングと 呼びます。
BBのMULTI PLAYER関連のブロック フィルターでMulti Playerで絞りこみます。基本的な機能を実装したブロックがいくつか提供されてい ます。 Auto Machmaking セッション(ルーム)の選択まで自動で行います。 ロビーやセッションがあればそこに参加し、なければ作成するよ うに動きます。 Network Grabbable Object 全プレイヤーがつかむことのできるネットワークオブジェクトを 作成します。 Player Name Tag プレイヤーの名前(Questにログインしているユーザー名)を取得 し表示します。 Networked Avatar Metaのアバターを表示します。Metaアカウントで作成したア バターをそのまま使うことができます。 Colocation 現実空間の空間地図の座標系をマルチプレイヤーで共有します。 Player Voice Chat Questのマイクを使い、ネットワーク越しに音声チャットを使 えるようにします。
MULTI PLAYER系のBLOCKとパッケージの依存関係 通信にPhotonかNetcodeのどちらかを選択して利用します。それぞれで利用パッケージが異なります。 Voice Chat利用の場合は、Photonを選択することとなります。 利用パッケージ Photon Fusion 利用 Auto Machmaking Photon Fusion 〇 Network Grabbable Object 〇 Player Name Tag 〇 Networked Avatar 〇 Colocation 〇 Photon Voice Unity Netcode 利用 共通 〇 〇 〇 〇 〇 Relay 〇 〇 〇 〇 〇 Lobby 〇 〇 〇 〇 〇 〇 〇 〇 Meta Avatars SDK 〇 〇 Netcode for GameObjects Meta XR Platform SDK Player Voice Chat 〇
COLOCATIONブロックの追加 新しいシーンを作成し、Main Cameraを削除します。 ColocationをドラッグアンドドロップでHierarchyに配置します。ImplementationにNetcodeか Photonを選択します。Photon Fusionを選択しConfirmを押下します。
QUESTアプリのアプリIDをセット Meta Quest Developer Centerで アプリ登録を行い、アプリIDの発行 User IDとUser Profileのプラットフォーム機能への アクセス許可の承認 を行う必要があります。「共有スペーシャルアンカーの サンプル実行」の章に説明がありますのでそちらを参照 してください。 メモしたアプリIDを入力しセットします。
NETWORK GRABBABLE OBJECTブロックの追加 Network Grabbable ObjectをドラッグアンドドロップでHierarchyに配置します。Use Gravityの チェックを外し、Confirmを押下します。
実行して確認する Quest 2台にBuildしたapkをインストールします。 2台のQuestでアプリを起動します。 だいたい現実の同じ位置にCube(Network Grabbable Object)が表示されます。同じ位置に表示されるのは Shared Spacial Anchorsで現実空間での位置の同期が行われるためです。また位置同期は初回起動時のみな ので、位置の同期のやり直しが必要な場合は自分で実装を組み込む必要があります。 片方のQuestでCubeをつかみ移動させると、もう片方のQuestでCubeが移動するのが確認できます。
アバター表示の追加 Meta Questのログインユーザーで設定しているアバターを使ってみましょう、Network Avatarをド ラッグアンドドロップでHierarchyに配置します。
INTERACTION SDKで表示されている手を消す ハンドトラッキングを利用する場合、Interaction SDK側での手の表示アバターの手が二重に表示され ています。アバターの手だけで良いので、HandVisualRight/Leftを非Activeにします。
AVATARSの使用の有効化 Meta Quest Developer CenterでUser ID/User Profile/Avatarsの使用のリクエストを作成します。 作成したリクエストを送信します。(下記は既にUser ID/User Profileを申請済み。)
実行して確認する Quest 2台にBuildしたapkをインストールします。 2台のQuestでアプリを起動します。 Meta Questにログインしているユーザーのアバターが表示されれば成功です。 正常にアバターが取 得できると、表示が アバターにかわりま す。 ※Meta Link(PCのEditor上)で実行した場合は正常に表示され ましたが、Quest実機の場合は失敗しました。
28.ハンドとコントローラーのマルチモーダル(同時利用)
マルチモーダルとは 手とコントローラーを同時に使うことができる機能です。Core SDK v59以降で利用できます。 瞬時の切り替え 手とコントローラーの切替を即座に行えます。 コントローラーと手の併用 片手でコントローラー、片手はハンドトラッキングという具合に併用ができます。 シングルコントローラー 片手だけコントローラーを使うなど片方だけの利用ができます。 コントローラの場所の表示 手を使っているときに、ユーザーにコントローラーの場所を示し手にとらすことができます。 Quest Pro/Quest3/Quest2(V68以降)が対応しています。Questのコントローラーには対応していないの で注意してください。Quest ProのコントローラーをQuest2とペアリングして利用する場合は、V65-67 でもこの機能を利用できます。 ワイド モーション モード (WMM)、インサイドアウト ボディ トラッキング (IOBT)、およびフル ボディ合 成 (FBS)、ジェスチャーコントロールのFast Motion Mode (素早い手の動きのトラキング)との併用ができ ません。
ヘッドトラッキングの設定 PackagesのMeta XR COre SDKのPrefabsフォルダにある。OVRCameraRigを Hierarchy(Scene)上にドラッグアンドドロップします。これで基本の頭のトラッキングができます。 不要になったMain Cameraを削除します。 OVR Managerコンポーネントで、Origin TypeをFloor Levelにします。
マルチモーダルの設定 OVRCameraRigのOVR Managerコン ポーネントで、マルチモーダルの設定を行い ます。 Simultaneous Hands And Controllers: true Hand Tracking Support:Controllers And Hands Launch Simultaneous Hands and Contollres:true
手に持っていないコントローラートラッキングの設定① PackagesのMeta XR Core SDKのPrefabsフォルダにある。OVRControllerPrefabを Hierarchy(Scene)上のLeftHandAnchorDetached(RightHandAnchorDetached)の下に、ド ラッグアンドドロップします。
手に持っていないコントローラートラッキングの設定② ドラッグアンドドロップしたOVRControllerPrefabを選択し、InspectorでControllerにTouch、 Show StateにController Not in Handを選択します。両手とも同じ設定を行います。
手に持っているコントローラートラッキングの設定① PackagesのMeta XR Core SDKのPrefabsフォルダにある。OVRControllerPrefabを Hierarchy(Scene)上のLeftControllerHandAnchor(RightControllerHandAnchor)の下に、ド ラッグアンドドロップします。
手に持っているコントローラートラッキングの設定② LeftControllerHandAnchor(RightControllerHandAnchor)の下のOVRControllerPrefabを選択 し、InspectorでControllerをLtouch(RTouch)に、Show StateをController Handに設定します。
ハンドトラッキングの設定① PackagesのMeta XR Core SDKのPrefabsフォルダにある。OVRHandPrefabを Hierarchy(Scene)上のLeftHandOnControllerAnchor(RightHandOnControllerAnchor)の下に、 ドラッグアンドドロップします。
ハンドトラッキングの設定② LeftHandOnControllerAnchor(RightHandOnControllerAnchor)の下のOVRHandPrefabを選 択し、Hand / Skelton / Mesh Typeを左手(右手)に、Show StateをController Not in handに設 定します。
動作をEDITORで確認 Meta QuestをUSBケーブルで接続(AirLinkでも可)し、Quest Link起動。 Unity Editorで実行します。コントローラーをもって認識するか? するか確認します。 コントローラーを置いて手を認識
SHOW STATEの説明 コントローラーの表示を制御する、Show Stateの種類です。 どの状態で表示するか 意味 Always コントローラーとハンドの状態をみなくなり、自動的に無効になりません。 Controller in Hand or no Hand コントローラーがユーザーの手の中にない場合、またはハンド トラッキングが完全に無効になっている場合、こ のオブジェクトが無効になることを意味します。 Controller in Hand コントローラーが現在ユーザーの手の中にある場合、オブジェクトが有効になることを意味します。 Controller Not in Hand オブジェクトがユーザーの手にある場合、オブジェクトが無効になることを意味します。これは、コントロー ラーが切り離された状況で使用されます。つまり机の上に置いた状態などです。 No Hand ハンドトラッキングが有効で、手が存在する場合、オブジェクトのレンダリングが無効になります。
29.XR AUDIOを試す アンビソニックス音源
3Dオーディオ AmbiXフォーマットのアンビソニックオーディオの再生をサポートしています。 アンビソニックオーディオとは 3Dオーディオのフォーマットで、シーンベースの球体の音場で録音・再生が可能です。 動画のAudioにも埋め込み可能なので、360度動画をアンビソニック対応にすることができます。 フォーマット 内容 オブジェクトベース オブジェクトにAudio Source(音源と音響)のデータを追加して、Listenerの 位置で聞こえる音をリアルタイムで計算にして再生させます。 シーンベース Listenerのまわりの空間全体を、空間マイクを使って音の位置や移動を録音し たもの、それを再生するものです。
360°VIRTUAL REALITY AUDIO RECORDER アンビソニックス方式のVRマイクの例 アンビソニックス左右(水平方向)、上下(仰角)、前後(奥行き)360°全方位の音を収録するア ンビソニックス録音が可能。アンビソニックスBフォーマット(FuMa、Ambix)への変換可能です。 バイノーラル方式の録音をサポート。 https://zoomcorp.com/ja/jp/handheld-recorders/handheld-recorders/h3-vr-360-audio-recorder/
AMBISONIC SOUNDの音源を入手 Ambisonic Soundのサンプルを入手します。 https://library.soundfield.com/browse/Ambience/Urban
AMBISONICの設定 ダウンロードしたAmbiXのファイルをUnityに取り込みます。 Audio Clipを選択し、InspectorでAmbisonicにチェックを入れApllyで適用します。
META XR AUDIO SDKをインポートする Package Managerを開き、Meta XR Audio SDKをインストールします。
AUDIO設定 DSPバッファサイズは、Best latencyに設定します。プラットフォームでサポートされる最小バッ ファサイズに設定し、全体的なオーディオの遅延を減らします。 Project SettingsのAudioを確認します。Spatializer PluginとAmbisonic Decoder PluginがMeta XR Audioに設定されていることを確認します。
LISTENER環境の作成 新しくシーンを作成し、OVRCameraRigを配置し、不要になったMain Cameraを削除します。 OVRCameraRigのCenterEyeAnchorのAudio Listenerにチェックをいれます。
AUDIO SOURCEの作成 空のGame Objectを追加し、EnvironmentalSoundsという名前に変更します。 EnvironmentalSoundsに、MetaXRAudioSourceコンポーネントを追加します。
AUDIO設定 MetaXRAudioSourceコンポーネントを追加したらAudio Sourceが自動で追加されます。 Spatializeにチェックは入れません。(入れるとモノラルになりAudio Source位置からの音源として 使われます。) ダウンロードしたAudio Clipを参照に設定します。
実行して確認する ビルドする場合は、QuestをUSBケーブルで接続しBuild And Runで実機で動作確認します。 Quest Linkを利用する場合は、USBでPCに接続(もしくはAir Link)しPlayを押下します。 目をつぶり音に集中します、頭の向きをかえながら音がどこから聞こえてくるか確認します。
31.コントローラーでの移動 OVRPLAYERCONTROLLER
環境の準備 新規にシーンを作成します。移動できるスペースが必要なので、Cubeで床をFloorという名前で作成 します。 Colliderが無いとプレイヤーが自由落下してしまうので、Box Colliderがついている必要があ ります。 Main Cameraを削除します。
OVR PLAYER CONTROLLERの設定① OVRPlayerControllerを検索し、シーンに追加します。 プレハブの中にあるOVRCameraRigのOVR ManagerのTracking Origin TypeをFloor Levelに変 更します。
OVR PLAYER CONTROLLERの設定② UnityのCharacter Controllerと、OVR Player Controllerのコンポーネントで移動速度や回転角度の 設定が行えます。
実行して確認する ビルドする場合は、QuestをUSBケーブルで接続しBuild And Runで実機で動作確認します。 Quest Linkを利用する場合は、USBでPCに接続(もしくはAir Link)しPlayを押下します。 左右のコントローラのジョイスティックを使い、移動・回転ができます。
30.コントローラーでテレポート移動
テレポートで移動する ジョイスティックの移動では、ベクション(視界の大半が動いた場合に自分が移動していると感じる錯 覚の)が生じてしまうため、視覚から感じる移動と、身体感覚的に移動していないことによるずれから VR酔いをしやすくなります。 ベクションを回避するには 1. 自分の体を使って本当に移動させる。体の動きに合わせて、視界が移動。 2. 移動の途中をみせず、一気に移動先にワープさせる。 3. 視界を狭めて、視界の大きな範囲を変化させない。 ここからは、2つ目の方法であるテレポートを作ります。
AI NAVIGATIONをインストール Package Managerを開き、AI Navigationをインポートします。
環境の準備 新規にシーンを作成します。移動できるスペースが必要なので、Cubeで床をFllorという名前で作成し ます。Colliderが無いとプレイヤーが自由落下してしまうので、Box Colliderがついている必要があり ます。 障害物用にCubeをいくつか追加します。 Main Cameraを削除します。 OVRCameraRigとOVRInteractionプレハブを追加し、前セクションの「Interaction sdkを使う」 を参考に設定を行います。
FLOORにNAVI MESHを設定する HierarchyからFloorと障害物のCubeを選択し、InspectorでStaticに設定します。 WindowメニューのAIから、Navigationのパネルを開きます。
歩ける領域の定義 Navigationのパネルから、Bakeボタンを押して歩ける領域の設定を行います。
TELEPORT INTERACTABLEの設定 空のGame Objectを追加し、Walkableという名前に変更します。Teleport Interactable、Nav Mesh Surface(Meta提供の方)コンポーネントを追加します。 Teleport InteractableのSurfaceに、Nav Mesh Surfaceの参照を設定します。 Nav Mesh SurfaceのArea Name にWorkableと入力します。
RETICLE DATA TELEPORTの設定 WalkableにReticle Data Teleportコンポーネントを追加します。 Reticle ModeにValid Targetを設定します。 (移動可能なオブジェクトにはValid Target、移動不可のオブジェクトにはInvalid Targetを設定しま す。)
TIPS:COLLIDERの表面をテレポート先から除外する場合 Collider Surfaceを使います。Reticle Data TeleportをInvarid Targetに設定します。
LOCOMOTORの設定① 空のGameObjectをLocomotionという名前で作成し、PlayerLocomotorコンポーネントを追加しま す。
LOCOMOTORの設定② PlayerLocomotorのPlayer Originに、OVRCameraRigの参照、Player HeadにCenterEyeAnchor の参照をセットします。
AXIS 2Dの設定(左手) LeftControllerの下に空のGameObjectをControllerFeaturesという名前で作成し、OVRAxis2Dコ ンポーネントを追加します。 ControllerにL Touch、Axis 2DにPrimary ThumbstickとPrimary Touchpadを設定します。
AXIS 2Dの設定(右手) 左右で、コントローラーの割り当てが違うので注意。RightControllerの下に空のGameObjectを ControllerFeaturesという名前で作成し、OVRAxis2Dコンポーネントを追加します。 ControllerにR Touch、Axis 2DにPrimary ThumbstickとPrimary Touchpadを設定します。
LOCOMOTION INTERATORの設定① CLocomotionControllerInteractorGroupを検索し、ControllerInteractorsの配下に追加します。 両手に 実施
LOCOMOTION INTERATORの設定② CotrollerInteractorsに、追加したInteractorの参照を設定します。 両手に 実施
LOCAMOTION EVENTS CONNECTIONの設定 HandlerにPlayer Locomotorの参照を設定します。 両手に 実施
SELECTORの設定 SelectorのInput AxisにOVR Axis 2Dの参照を設定します。 両手に 実施
ACTIVATE/DEACTIVATEの設定 ActivateとDeactivateのInput AxisにOVR Axis 2Dの参照を設定します。 両手に 実施
CONTROLLER TURNER INTERACTORの設定 ControllerTurnerInteractorのAxis 2DにOVR Axis 2Dの参照を設定します 両手に 実施
実行して確認する ビルドする場合は、QuestをUSBケーブルで接続しBuild And Runで実機で動作確認します。 Quest Linkを利用する場合は、USBでPCに接続(もしくはAir Link)しPlayを押下します。 左右のコントローラのジョイスティックを使い、ワープ移動・回転ができます。
32.音に合わせてコントローラーを振動 ハプティック クリップの作成と再生
ハプティクスクリップとは ハプティクスクリップは振動を定義した.hapticという拡張子のファイルで、 Meta XR Haptics SDK で効果音などに合わせてコントローラーを振動させる仕組みです。 Meta Haptics Studioを使うことで振動を作成することができます。音をもとに振動を作成するのが 基本的な作り方になります。
META HAPTICS STUDIOのインストール 音を振動の波であるハプティクスクリップに変換するツールは下記からダウンロードすることができま す。(以下、Windows版で説明します。) https://developer.oculus.com/downloads/package/meta-haptics-studio-win https://developer.oculus.com/downloads/package/meta-haptics-studio-macos ダウンロードしたzipファイルを解凍し、 meta-haptics-studio-desktop-win-1.0.0.exeを実行しイ ンストールを行います。 最初に起動した際に、利用条件の確認が表示されるので、Acceptを選択します。
META HAPTICS STUDIO VR APPLICATIONのインストール Meta QuestでStoreを開き、Hpaticsを検索し、Meta Haptics Studioをインストールします。 インストールが完了したら、 Meta Haptics Studioを起動します。
実機で振動確認するためQUESTとPCの接続 QuestとPCを同一のネットワークに接続。Questアプリで表示されたPCを選択しConnectボタンを 押下します。 PC側で右上のデバイスアイコンを選択、セキュリティコードを表示。Questアプリでその番号を入力 します。
ハプティクスクリップの作成 音をベースにハプティクスクリップを作成します。New Projectを選択し、サウンドファイルを選択 します。 GainやSensitivityなどのパラメータ調整や、頂点を手で修正することで狙いの振動を作成します。 クリップを追加する場合は、⊕ボタンで追加を行います。
振動の確認 Quest側のアプリでPCで作成中のクリップが表示されています。プレイボタンを押下すると実機のコ ントローラーに振動が再生されます。
ハプティクスクリップのエクスポート Meta Haptics Studioの左側のクリップの一覧から出力するクリップを選択し、Exportボタンを押下 することで.hapticファイルを作成することができます。
META XR HAPTICS SDKのインストール UnityのパッケージマネージャからMeta XR Haptics SDKをインストールします。
.HAPTICファイルをUNITYへ取り込む 新しくシーンを作成し、OVRCameraRigを配置し、不要になったMain Cameraを削除します。 OVRHandPrefabをHierarchy(Scene)上のLeftHandAnchor(RightHandAnchor)の下に、ドラッ グアンドドロップします。 作成した.hapticファイルをUnityのAssetsフォルダへコピーします。
HAPTIC CLIP PLAYERを動作させるスクリプトを作成 HapticClipPlayerをインスタンス化して、HapticClipをプレイ、ストップするスクリプトを作成しま す。 protected virtual void Update() { try { if (OVRInput.GetDown(OVRInput.Button.PrimaryIndexTrigger, OVRInput.Controller.LTouch)) { _hapticClipPlayer.Play(Controller.Left); } if (OVRInput.GetUp(OVRInput.Button.PrimaryIndexTrigger, OVRInput.Controller.LTouch)) { _hapticClipPlayer.Stop(); } } catch (Exception e) { Debug.LogError(e.Message); } } using UnityEngine; using Oculus.Haptics; using System; public class HapticsPlayer : MonoBehaviour { [SerializeField] HapticClip _hapticClip; [SerializeField] HapticClipPlayer _hapticClipPlayer; protected virtual void Start() { _hapticClipPlayer = new HapticClipPlayer(_hapticClip); } protected virtual void OnDestroy() { _hapticClipPlayer.Dispose(); } protected virtual void OnApplicationQuit() { Haptics.Instance.Dispose(); } }
スクリプトをコンポーネントとして追加 クリップに.hapticファイルを設定します。
実行して確認する ビルドする場合は、QuestをUSBケーブルで接続しBuild And Runで実機で動作確認します。 Quest Linkを利用する場合は、USBでPCに接続(もしくはAir Link)しPlayを押下します。 左のコントローラの人差し指ボタンを押下するとコントローラーの振動が開始、離すことにより振動が 停止します。
33.現実のキーボードを仮想空間に表示させる
現実世界のキーボードを仮想空間に持ちこむ • 対応しているキーボードであれば、現実空間のキーボードを仮想世界に表示することができます。対応して いるキーボードは下記のとおりです。 • Logitech K830 • Logitech K375s • Logitech MX Keys Universal (グラファイト) • Logitech MX Keys for Mac (スペースグレー) • Logitech MX Keys Mini Universal (ペールグレー) • Logitech MX Keys Mini for Mac (ペールグレー) • Apple Magic Keyboard • Apple Magic Keyboard (テンキー付き) • Apple Magic Keyboard (Touch IDおよびテンキー付き) • Microsoft Surfaceキーボード
対応キーボードをQUESTとつなぐ 今回はK830を利用します。Questを起動し設定アイコンから設定を開き、デバイスからBluetoothを 選択。ペアリングボタンを押下して、新しいデバイスとペア設定でペアリングを行います。
利用するキーボード設定 キーボードを選択し、Bluetoothキーボードの編集ボタンを押下します。 メーカー選択、キーボード選択を行います。
OVR TRACKED KEYBOARDの追加 新しくシーンを作成し、OVRCameraRigを配置し、不要になったMain Cameraを削除します。 Packagesより、OVRTrackedKeyboardをシーンに追加します。
OVR TRACKED KEYBOARDのコンポーネント OVRTrackedKeyboardのコンポーネント、ここにPassthroughのコンポーネントも含まれます。
OVR MANAGERの設定 HierarchyからOVRCameraRigを選択し、OVR Managerの設定で、Tracked Keyboard Support とPassthroughの設定を行います。
実行して確認する ビルドする場合は、QuestをUSBケーブルで接続しBuild And Runで実機で動作確認します。 Quest Linkを利用する場合は、USBでPCに接続(もしくはAir Link)しPlayを押下します。 ※Quest Linkでも動作するという情報もありましたが、ビルドしないと動作しませんでした。 対応しているキーボードを見ると、そこにCGが表示され手を近づけると自分の手(手の部分がパスス ルー)で表示されます。
TIPS : キーボードを選択する スクリプトからKeyboard Selection Dialogメソッドを実行することで、Questにキーボードの選択 ダイアログを表示することができます。 リモートキーボードの場合 trackedKeyboard.LaunchRemoteKeyboardSelectionDialog() ローカルキーボードの場合 trackedKeyboard.LaunchLocalKeyboardSelectionDialog()
34.ワイドモーションモード(WMM)を利用する
ワイドモーションモードとは 手がヘッドセットの視野外にある場合でも手を追跡し、違和感のない手のポーズを表示する仕組みです。 内部的にはインサイドアウトボディトラッキング(IOBT)を使用し、手の追跡が失われた場合でも、手の位 置を推定します。
WMMの設定 新規にシーンを作成し、「Interaction sdkを自分で組み 立てる」の章を完了した状態を作成します。 Camera Rigを選択し、OVR ManagerのWide Motion Mode Hand Poses Enableをチェックします。
ボディトラッキングを有効化 OVR ManagerのQuest Featuresにある、Body Tracking SupportをRequiredにします。
35. OVR METRICS TOOLでパフォーマンス測定
OVR METRICS TOOLのインストール Meta Quest実機上で、パフォーマンスをモニタリングするためのツールで、Meta Horizon Storeで 入手可能です。Questの画面にオーバーレイで表示するHUDモードと、CSVで記録するREPORT モードがあります。 https://www.oculus.com/experiences/quest/2372625889463779/ Meta Horizon Storeで入手するを選択しインストール、Questをネットに接続するとインストールさ れます。
OVR METRICS TOOLの使い方(HUDモード) Questのアプリ一覧からアプリを起動。Enable Persistent Overlayがオンで情報が表示されます。
OVR METRICS TOOLの使い方(REPORTモード) Record all captured metrics to csv filesをオンにするとCSVファイルに記録されます。
プリセットを選択する いくつか表示内容のプレセットが用意されています。状況に応じて使い分けましょう。 使わないときはNoneにしておき、 Enable Persistent OverlayとRecord all captured metrics to csv filesをオフにします。 取得すること自体がオーバーヘッドになることに注意します。Advancedは負荷が高いため、基本は BASICを使うようにしてください。 NONE BASIC ADVANCED ADVANCED WITH MEMORY
カスタム表示 表示・記録する指標値を自分で選択することができます。GRAPHS、STATSタブを選択しVisible GraphsとVisible Statsに加えることでカスタマイズが可能です。
36.QUESTのパフォーマンス(CPU/GPU)設定
CPUとGPUのレベル設定 CPUとGPUの利用コア数やクロックを調整することで、Questの性能を変更することができます。温 度の上限値に達するまで性能向上をはかることが出来ます。ただし、バッテリーの消費が大きくなるた め稼働時間とのトレードオフになります。 CPUの設定方法 OVRManager.suggestedCpuPerfLevel = OVRManager.ProcessorPerformanceLevel.SustainedLow; GPUの設定方法 OVRManager.suggestedGpuPerfLevel = OVRManager.ProcessorPerformanceLevel. SustainedHigh; ProcessorPerformanceLevel CPUレベル範囲 GPUレベル範囲 PowerSavings 0〜4 0〜4 SustainedLow 2~4 1~4 SustainedHigh 4 3~5 4~5/6 3~5 *Meta Quest 2とMeta Quest Proのみ Boost
設定値と動作クロック Quest3の動作クロック プロセッサー 動作クロック コア数 説明 CPU Level 0 0.69 GHz 3 CPU Level 1 1.09 GHz 3 常に利用可能 CPU Level 2 1.38 GHz 3 CPU Level 3 1.65 GHz 3 CPU Level 4 1.96 GHz 3 パススルーが有効でない場合に利用可能。 CPU Level 5 2.05 GHz 3 CPUレベル4が利用可能で、CPU and GPU level tradingが-1設定されてにいる場合に利用可能 GPU Level 0 285 MHz - 常に利用可能 GPU Level 1 350 MHz - GPU Level 2 456 MHz - GPU Level 3 492 MHz - GPU Level 4 545 MHz - GPU Level 5 599 MHz - パススルーが有効でない場合に利用可能。 CPU and GPU level tradingが+1に設定されているかOVR ManagerのEnable Dynamic ResolutionをTrueに設定されている場 合に有効。GPUレベル4でGPU使用率が特定のしきい値を超えた場合にこのモードとなる。
設定値と動作クロック Quest2/Quest Proの動作クロック プロセッサー 動作クロック コア数 説明 CPU Level 0 0.71 GHz 3 CPU Level 1 0.94 GHz 3 CPU Level 2 1.17 GHz 3 常に利用可能 CPU Level 3 1.38 GHz 3 CPU Level 4 1.48 GHz 3 Quest Pro Quset 2 CPU Level 5 1.86 GHz 3 CPUレベル4が利用可能で、デュアルコアモードでない場合に有効。 CPU Level 6 2.15 GHz 2 CPUレベル4が利用可能で、デュアルコアモードの場合に有効。 GPU Level 0 305 MHz - 常に利用可能 GPU Level 1 400 MHz - GPU Level 2 442 MHz - GPU Level 3 490 MHz - GPU Level 4 525 MHz - Quest Pro Quset 2 GPU Level 5 587 MHz - OVR ManagerのEnable Dynamic ResolutionをTrueに設定されている場合に有効。GPUレベル4でGPU使用率が特定のしきい値 を超えた場合にこのモードとなる。 : パススルー、アイトラッキング、フェイストラッキング、ボディトラッキングが有効でない場合に利用可能。 : 常に利用可能 :パススルー、アイトラッキング、フェイストラッキング、ボディトラッキングが有効でない場合に利用可能。 : 常に利用可能
デュアルコアモードの設定 Quest2・Proのデュアルコアモードは、Manifestに下記を追記する必要があります。
37. APPLICATION SPACEWARPでFPSを向上させる
APPLICATION SPACEWARPとは フレームをひとつ飛ばしでレンダリングすることで、見た目をあまり損なわずFPSを向上させることが できます。ひとつ飛ばしでレンダリングを省略したフレームは、前フレームのピクセル(Eye Buffer)が どこに移動するかを予測し表示します。 この予測にはモーションベクトル(フレーム間のピクセルの座標の差)とDepth(目からの距離)が使われ、 モーションベクトルをバッファに格納するシェーダーが必要となります。
必要条件 • OpenXR OVRPlugin v34以上 • Unity 2020の場合はカスタムOculus XR Plugin 2.0.0-preview.1以上、その他の場合はOculus XR Pluginの最新リリース • Unity 2020.3.22f1以上、Unity 2021.2.1f1以上、Unity 2022.3.1f1以上 • Unity2023以下の場合はASW非対応のため、URPの置き換えが必要。 URP Forkから入手できる、SpaceWarpに対応しているURPへ置き換える。
アプリでAPPSWを有効にする方法① Space Warp対応のURPパッケージをインストールする。 UnityプロジェクトフォルダのPackagesフォルダにあるmanifest.jsonを開きます。 ※ Unity6ではURPがASWに正式対応しており、アプリでAppSWを有効にする方法①の手順は不要です。 com.unity.render-pipelines.core、 com.unity.render-pipelines.universal、 com.unity.shadergraph のパッケージをdependenciesに追加します。 (下記は、Unity2022.3.xバージョンの場合。) 既にパッケージが同じパッケージ名で記載されている(重複した記載になる)ものは削除してください。 { "dependencies": { "com.unity.render-pipelines.core": "git+https://github.com/Oculus-VR/Unity-Graphics.git?path=/Packages/com.unity.render-pipelines.core#2022.3/oculus-app-spacewarp", "com.unity.render-pipelines.universal": "git+https://github.com/Oculus-VR/Unity-Graphics.git?path=/Packages/com.unity.render-pipelines.universal#2022.3/oculus-app-spacewarp", "com.unity.shadergraph": "git+https://github.com/Oculus-VR/Unity-Graphics.git?path=/Packages/com.unity.shadergraph#2022.3/oculus-app-spacewarp", "com.cysharp.unitask": "2.5.0", "com.meta.xr.sdk.core": "68.0.3", "com.meta.xr.sdk.interaction.ovr": "68.0.2", “com.unity.2d.sprite”: “1.0.0”, ・ ・
アプリでAPPSWを有効にする方法② Project SettingsのOculusのAndroidタブにある、Application SpaceWarpにチェックを入れます。 Playerの設定にある、Graphics APIsがVulkanになっていることを確認します。
C#でAPPSWの操作 SpaceWarpはスクリプトからオンオフの切り替えが可能です。 SpaceWarpのオンオフの切り替え OVRManager.SetSpaceWarp(bool enabled) SpaceWarpの有効無効の取得 OVRManager.GetSpaceWarp()
実行して確認する OVR Metrics Toolをインストールし、STATSでSpaceWarp FPSを出力するように設定します。 Build And Runで実機で動作確認します。 Metrics Toolの表示からFPSとASW FPSを参照し、期待のFPSが出ているか確認します。 ASW FPSが無効の場合、 ASW FPSは0表示されます。
38. MX INK(QUEST用スタイラスペン)を使う
MX INKとは Logicoolが販売するQuest用のスタイラスペンで、6DOFで動作する、3つ目のコントローラーとして 機能します。感圧式のボタンがあり、筆圧を3D空間上で再現することができます。 右手か左手に割り当てを行い、割り当てた方のコントローラーとスタイラスを択一で利用可能です。 Horizon OS Ver.69以降にて利用可能です。 コントロール ❶ フロントボタン 説明 このボタンは、仮想オブジェクトをつかむためによく使用されます。利き手では ない方の手のタッチ コントローラ グリップ ボタンと組み合わせて使用すると、 オブジェクトの拡大縮小や回転が可能になります。 ❷ リアボタン このボタンは、メニューを開くなどの三次コントロールに使用できます。 ❸ Metaボタン これは、Meta Touch コントローラーの Meta ボタンに相当します。つまり、 押すとシステム メニューが表示され、長押しすると中心に戻ります。このボタン を 5 秒間押し続けると、スタイラスの電源がオフになります。3 秒間押し続け ると、スタイラスの電源がオンになります。 ❹ アナログチップ アナログ チップを使用すると、物理的な表面に線を描くことができます。仮想面 と物理的な面を揃えて、デスクやホワイトボード上に描画面を再現することがで きます。 ❺ 中央ボタン 圧力5に敏感なボタンを使用すると、0 ~ 1 の範囲の値を報告できる入力が可 能になります。たとえば、この入力は、ボタンに加えられた圧力に基づいて空中 にさまざまな線幅を作成したり、押して UI 要素を選択したりするために使用で きます。
ペアリング スマートフォンアプリのMeta Horizonで新しいコントローラーとしてペアリングを行います。 アプリの指示通り手順を進めます。 METAボタンを3秒 間押し続けてスタ イラスの電源を入 れます。 METAボタンとリ アボタンの両方を4 秒間押し続けてペ アリングモードに 入ります。
スタイラスの設定 Questの設定にスタイラスの設定が追加されています。
サンプルプログラム 描画アプリ用のPrefabがLogicoolから提供されている。 https://logitech.github.io/mxink/Assets/logitech_mx_ink.unitypackage サンプルプログラム ペンでお絵描きできるプログラム、スタイラスの3Dモデルが用意されているのでスタイラスペンを表 示させたい場合は、こちらを参考にすればよい。サンプルプログラムを動かす場合、 Projectを開き、 後述のInput ActionsにMxInkActionsを追加する必要があります。 https://logitech.github.io/mxink/Assets/MX_Ink_Sample_App_v1.0.zip
META CORE SDK(V68~)での利用 新規にシーンを作成し、「Interaction sdkを自分で組み立てる」の章を完了した状態を作成します。 MxInkActions.assetを下記URLよりダウンロードし、UnityプロジェクトのAssetsフォルダにコピー します。 https://logitech.github.io/mxink/Assets/MxInkActions.asset
INPUT ACTIONSにMX INKを追加 Project SettingsのMeta XR、Input ActionsにMxInkActionsを追加します。
先端の位置の取得
GetActionStatePoseで取得します。
1cmくらいの球を作成して、このスクリプトをコンポーネントに追加すると先端に球が移動します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Stylus : MonoBehaviour
{
void Update()
{
string MX_Ink_Pose = "aim_right";
if (OVRPlugin.GetActionStatePose(MX_Ink_Pose, out OVRPlugin.Posef handPose))
{
transform.position = handPose.Position.FromFlippedZVector3f();
transform.rotation = handPose.Orientation.FromFlippedZQuatf();
}
}
}
スタイラスのアクティブ化の検出
GetCurrentInteractionProfileNameを使い、どのプロファイルが使われているか調べます。MX Ink
のプロファイル名は“/interaction_profiles/logitech/mx_ink_stylus_logitech”です。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Stylus : MonoBehaviour
{
void Update()
{
if (OVRPlugin.GetCurrentInteractionProfileName(OVRPlugin.Hand.HandRight)
== "/interaction_profiles/logitech/mx_ink_stylus_logitech") {
Debug.Log(“Active!!”);
}
}
}
スタイラスの値の読み取り
GetActionStateで値を取得できます。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Stylus : MonoBehaviour
{
float stylus_tip_value;
bool stylus_front_button;
float stylus_middle_value;
bool stylus_back_button;
bool stylus_docked;
void Update()
{
if (OVRPlugin.GetCurrentInteractionProfileName(OVRPlugin.Hand.HandRight) == "/interaction_profiles/logitech/mx_ink_stylus_logitech") {
OVRPlugin.GetActionStateFloat("tip", out stylus_tip_value);
OVRPlugin.GetActionStateBoolean("front", out bool stylus_front_button);
OVRPlugin.GetActionStateFloat("middle", out stylus_middle_value);
OVRPlugin.GetActionStateBoolean("back", out bool stylus_back_button);
OVRPlugin.GetActionStateBoolean("dock", out stylus_docked);}
}
}
触覚フィードバックのトリガー
TriggerVibrationActionでバイブレーションを発生させることができます。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Stylus : MonoBehaviour
{
float stylus_middle_value;
void Update()
{
if (OVRPlugin.GetCurrentInteractionProfileName(OVRPlugin.Hand.HandRight) == "/interaction_profiles/logitech/mx_ink_stylus_logitech") {
OVRPlugin.GetActionStateFloat("middle", out stylus_middle_value);
float duration = 0.01f;
float amplitude = stylus_middle_value;
OVRPlugin.TriggerVibrationAction("haptic_pulse", OVRPlugin.Hand.HandRight, duration, amplitude);
}
}
}
実行して確認する ビルドする場合は、QuestをUSBケーブルで接続しBuild And Runで実機で動作確認します。 Quest Link でも動作確認可能です、Quest Linkを利用する場合は、USBでPCに接続(もしくはAir Link)しPlayを押下します。
TIPS : レガシーコントローラーのマッピング MX Inkに対応していないアプリでも、コントローラー代わりにMX Inkを利用することができます。 コントローラーのボタンとのマッピングは下記の通り。 注意 スタイラスの位置は、Z軸で5.5cmのオフセットを持ちます。 先端値はX-axisとして読み取ることができますが、Inkとして使用する場合に比べ筆圧の精度が劣りま す。
39.実機でのDEBUG
実機でのデバッグ方法 下記の3つの方法を説明します。 ① Visual Studioを使い、Step実行でDebugする方法 ② Logcatを使い、Androidのログを表示する方法 ③ Canvasをシーン上に置き、ログを画面に表示する方法
①VISUAL STUDIOを使い、STEP実行でDEBUGする方法 実機にビルドする際に、Development BuildとScript Debuggingにチェックをいれます。
実機で実行 QuestをUSBで接続した状態で、Build And Runを選択し実機で実行します。
VISUAL STUDIOでデバッガーのアタッチ Visual Studioを開き、デバッグメニューからUnity デバッガーのアタッチを選択します。 インスタンスの選択が表示されるので、Android Playerで 接続中のQuestを選択しOKボタンを押下 します。
ステップ実行 ブレークポイントを設定し、ステップ実行で動作を確認しデバッグします。
②LOGCATを使い、ANDROIDのログを表示する方法 Package ManagerでUnity RegistryからLogcatをインストールします。
C#でログ出力 UnityのDebugでログを出力するようにコーディングします。 ビルドして実機で実行します。 using System.Collections; using System.Collections.Generic; using UnityEngine; public class DebugTest : MonoBehaviour { // Start is called before the first frame update void Start() { Debug.Log("Debug Start"); } // Update is called once per frame void Update() { Debug.Log("Debug"); } }
LOGCATの表示 USBでQuestと接続します。 メニューのWindowから、Analysis、Android Logcatを選択します。
ログの表示 実機のログが表示されます、FilterでUnityのC#で出力した内容を絞り込んで確認してください。
③CANVASをシーン上に置き、ログを画面に表示する方法 実行時に簡易的にログを見たい場合、ログをCanvasに出すCanvasWithDebugプレハブが使えます。 しかし以前の開発環境であるOculus Integrationには含まれていたのですが、Meta SDKでは用意さ れていないようです。
CANVASWITHDEBUGのエクスポート Oculus Integration v57がインストールされている環境から、DebugUI配下のAssetをExportしま す。
CANVASWITHDEBUGプレハブの配置 CanvasWithDebugをインポートし、 CanvasWithDebugプレハブをシーン上のカメラから見える 位置に配置します。 DebugUIBuilderコンポーネントのText Prefabへの参照が落ちているので設定しておきます。
SCRIPTでログを出力 DebugUIBuilder.instanceを使い、ラベル(AddLabel)もしくはテキスト(AddTextField)をCanvas に出力します。 using System.Collections; using System.Collections.Generic; Using UnityEngine; Public class DebugTest : MonoBehaviour { // Start is called before the first frame update void Start() { DebugUIBuilder.instance.Show(); DebugUIBuilder.instance.AddLabel(„▼▼▼ Debug Start ▼▼▼”, DebugUIBuilder.DEBUG_PANE_CENTER); } // Update is called once per frame void Update() { DebugUIBuilder.instance.AddTextField(„▼▼▼ Text ▼▼▼”, DebugUIBuilder.DEBUG_PANE_RIGHT); DebugUIBuilder.instance.AddLabel(„▼▼▼ Label ▼▼▼”, DebugUIBuilder.DEBUG_PANE_LEFT); } }
実機で実行 UIの要素(LabelやText)が無限大に追加されていく仕様のため、大量のログを出力するには向きません。 しかしボタンの追加なども可能で、テスト時にボタンにメソッドを割り当てて呼び出すこともできるの で、テスト機能を呼び出しこともできます。やりたいことに合わせての使い分けが必要です。
40.VOICE SDKで声をテキストに変える SPEECH TO TEXT
できること 変換 声をテキストに変えるSTT(Speech to Text) テキストを声に変えるTTS(Text to Speech) 対話 NLP(自然言語処理) コンポーザー グラフによる対話 応答 決定
自然言語処理(NLP)の概要 Voice SDKでは、自然言語処理の機能はwit.aiを利用します。 おおまかな流れは、ユーザーの音声による発話をテキスト化し認識されたインテントをハンドリング し、抽出されたエンティティにより処理を行うという流れです。 wit.ai(NLP) きょう、えーさんにおかねを ひゃくえんかえす 発話のテキスト :今日、Aさんにお金を100円返す インテント :お金を返す …タスク エンティティ :今日、Aさん、100円 …タスク実行に必要な情報 Response Handler(Response Matcher / Value Matcher) 返金処理の実行
自然言語処理のWIT.AIの準備 wit.aiのホームページに行き、Metaアカウントでログインします。 https://wit.ai/
アプリの作成 New Appを押下し、新規にアプリを作成します。アプリ名に適当な名前をつけ、言語に日本語を選択 し、作成を行います。
ACCESS TOKENの確認 ManagementのSettingsにある、Server Access Tokenをメモしておきます。
VOICE SDKのインストール Package Managerを開き、My Assetsから購入したvoiceを検索します。 Meta Voice SDK – Immersive Voice Commandsを選択しインストールします。
ANDROIDのパーミッション設定 Project SettingsのPlayer、Other SettingsにあるInternet AccessをRequireに設定します。
VOICE SDKの設定① メニュー(Oculus -> Voice SDK)から、Get Startedを選択します。
VOICE SDKの設定② 言語に日本語を選択し、Createを押下します。 wit設定を名前を付けて保存します。
ビルトインNLP(自然言語処理)の対応言語 対応言語は下記のとおり、今回は日本語を利用します。 言語 ISO 639-1コード 中国語 zh オランダ語 nl フランス語 fr ドイツ語 de イタリア語 it 日本語 ja 韓国語 ko ポーランド語 pl ポルトガル語 pt ロシア語 ru スペイン語 es スウェーデン語 sv トルコ語 tr
VOICE SDKの設定③ Wit ConfigurationsのServer Access Tokenに先ほどメモしたAccess Tokenを記入します。 Refreshボタンを押下します。wit.aiからアプリケーションの情報を取得します。
APP VOICE EXPERIENCEの追加 新しくシーンを作成し、OVRCameraRigを配置し、不要になったMain Cameraを削除します。 メニュー(Assets -> Ctreate -> Voice SDK)から、Add App Voice Experience to Sceneを選択し ます。
APP VOICE EXPERIENCEの設定① Wit Configurationに先ほどVoice SDKの設定で作成した、 wit設定を指定します。
UIの作成 状態を表示するためのTextと、音声認識の開始を伝えるためのボタンを作成します。 CanvasをCenterEyeAnchorの配下に作成。StatusとActivate Buttonに名前を変更します。 Canvas配下にText -TextMeshProとButton -TextMeshProを配置します。 CanvasのRender ModeをWorld Spaceに変更し目の前に表示されるように調整します。
イベントのハンドリング(失敗…) App Voice ExperienceのEventsを設定し、Statusに状態を表示するつもりが動かない。 OnStartListeningの開始時に”Listening…”を表示 発話の途中で返却された文字を表示 発話の完了時に返却されたすべての文字を表示 エラー時に”Error”を表示 完了時に次の手順の案内を表示
イベントのハンドリング(成功) StatusからTextMeshProコンポーネントを削除。Add ComponentでVoiceTranscriptionLabelコ ンポーネントを追加します。 Voice Servicesにシーン上のApp Voice Experienceの参照を設定します。
VOICE TRANSCRIPTION LABEL VoiceTranscriptionLabelの中身では、イベントのリスナーを設定する形になっています。 // Add service delegates private void OnEnable() { if (_voiceServices != null) { foreach (var service in _voiceServices) { service.VoiceEvents.OnStartListening.AddListener(OnStartListening); service.VoiceEvents.OnPartialTranscription.AddListener(OnTranscriptionChange); service.VoiceEvents.OnFullTranscription.AddListener(OnTranscriptionChange); service.VoiceEvents.OnError.AddListener(OnError); service.VoiceEvents.OnComplete.AddListener(OnComplete); } } }
声の認識を開始させる Activate Buttonに、Add ComponentでVoice Activation Buttonコンポーネントを追加します。 Voice Serviceにシーン上のApp Voice Experienceの参照を設定します。
ボタンを押せるように設定 「遠くの物(Game Object)を選択する」や、「Direct touch UI(手でさわって選ぶUI)の作成」の章を 参考にActivate ButtonをVR環境で押せるように設定します。
実行して確認する ビルドする場合は、QuestをUSBケーブルで接続しBuild And Runで実機で動作確認します。 Quest Linkを利用する場合は、USBでPCに接続(もしくはAir Link)しPlayを押下します。 Activate Buttonを押してから発話すると、テキストとなって発話内容が返却されテキストとして表示 されます。 ※wit.aiに接続するため、ネッしトワーク接続が必要です。
41.ガーディアンのバウンダリー(境界)表示を消す
バウンダリー(境界)表示を消す V66以降で、Passthrough時にバウンダリー表示をOVRBoundary.SetVisible()で消すことができま す。 public class OVRBoundaryController : MonoBehaviour { OVRBoundary _OVRBoundary; void Start() { // アクティブなバウンダリーシステムを取得 _OVRBoundary = OVRManager.boundary; } void Update() { if (OVRInput.Get(OVRInput.RawButton.A)) { _OVRBoundary.SetVisible(true); } if (OVRInput.Get(OVRInput.RawButton.B)) { _OVRBoundary.SetVisible(false); } } } ※SetVisible(true)後に、GetVisibleするとfalseとなっ ており書き換わらない。調査中。
42.やってはいけないMETA QUEST
利用規約より https://www.meta.com/jp/legal/quest/ 商用利用規約より 認定販売店以外が、Meta Questやアクセサリーを販売、貸与してはならない。 Meta Quest規約より 保護者は10歳未満のお子様のためにアカウントを作成することはできず、10歳未満のお子様はMeta Quest 2 や3を利用できません。
43.関連情報のご紹介
META QUEST開発関連資料 Meta Quest開発関連では、下記資料も公開中です。 https://www.docswell.com/s/Ovjang/ZG11ED -2024-08-31-123936 https://www.docswell.com/s/Ovjang/5DL ERK-Quest https://www.docswell.com/s/Ovjang/5P9P 12-2024-02-08-173200