xr-development について
GDScriptまたはC#でOpenXRプロジェクトを開発するGodot開発者向けのXRスキルです。Godot 4.3以降のセットアップ、操作、複合現実、プラットフォーム機能を扱います。
主な機能
- 01OpenXRの設定とセッション開始
- 02コントローラー入力とハンドトラッキング
- 03オブジェクトの把持とXR UI
- 04パススルー複合現実
- 05Quest向けエクスポートと性能設定
- 06Godot 4.5~4.7のXR機能
活用シーン
- 01コントローラーを使うVR操作の構築
- 02ハンドトラッキングとジェスチャー入力の追加
- 033Dシーン内での操作可能なUI表示
- 04XRプロジェクトのMeta Quest向けエクスポート
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ jame581/ godotprompter --skill xr-developmentインストール後、Claude Code で/xr-developmentを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/controllers-and-input.mdgodot-4-5-features.mdgodot-4-7-features.mdgrabbing-objects.mdhand-tracking.mdpassthrough.mdspatial-entities.mdxr-ui.md詳細
Godot 4.3+でのXR開発
すべての例は、非推奨APIを使用せずにGodot 4.3+を対象としています。まずGDScriptを示し、次にC#を示します。
関連スキル: 3Dレンダリングと環境については3d-essentials、3D物理インタラクションについてはphysics-system、XR以外の入力パターンについてはinput-handling、プラットフォームへのエクスポートについてはexport-pipelineを参照してください。
1. XRのセットアップ
OpenXRを有効にする
- OpenXRはエンジンに組み込まれているため、有効にするプラグインはありません。
- プロジェクト設定 → XR → OpenXR → Enabled →
true - プロジェクト設定 → XR → Shaders → Enabled →
true(XRシェーダーをサポートする場合) - レンダリング:
- Forward+またはMobileレンダラーを使用します(よりシンプルなシーンではCompatibilityも使用できます)
- プロジェクト設定 → Display → Window → VSync Modeを
Disabledに設定します(フレームタイミングはXRランタイムが制御します)
基本的なシーン構成
Main (Node3D)
├── XROrigin3D ← Player's physical space origin
│ ├── XRCamera3D ← Head-mounted display
│ ├── XRController3D (left) ← Left controller
│ │ └── LeftHandModel (MeshInstance3D or hand tracking)
│ ├── XRController3D (right) ← Right controller
│ │ └── RightHandModel
│ └── (XRBodyTracker via XRServer — optional full body tracking)
├── WorldEnvironment
└── GameWorld (Node3D)
└── ... level geometry
XRセッションの開始
extends Node3D
func _ready() -> void:
var xr_interface: XRInterface = XRServer.find_interface("OpenXR")
if xr_interface and xr_interface.is_initialized():
get_viewport().use_xr = true
else:
push_error("OpenXR not available")
public partial class XRMain : Node3D
{
public override void _Ready()
{
var xrInterface = XRServer.FindInterface("OpenXR");
if (xrInterface != null && xrInterface.IsInitialized())
GetViewport().UseXR = true;
else
GD.PushError("OpenXR not available");
}
}
2. コントローラーと入力
XRController3Dノード(各手に1つずつ、XROrigin3Dの子ノード)は、OpenXRアクションマップを介してボタンを公開します。デフォルトのアクションマップ名は、トリガー(trigger float、trigger_click)、グリップ(grip、grip_click)、サムスティック(primary Vector2、primary_click)です。サムスティックによる移動速度は、カメラではなくXROrigin3Dに適用します。
XRController3Dの完全な接続方法、OpenXRボタンのリファレンス、サムスティックによる移動の手順については、references/controllers-and-input.mdを参照してください。
3. ハンドトラッキング
ヘッドセットがハンドトラッキングに対応している場合(Quest 2+、Pico 4、一部のSteamVRセットアップ)、ランタイムはXRHandTrackers(/user/hand_tracker/left / right)を公開します。XRHandModifier3Dはこれらを使って手のスケルトンをポーズし、XRController3Dはハンドインタラクションプロファイルを介して引き続き選択/グリップ操作を受け取ります。ジェスチャー検出には、指の関節をサンプリングします。
ハンドトラッキングのノード設定、関節のサンプリング、ジェスチャー駆動のインタラクションについては、references/hand-tracking.mdを参照してください。
4. オブジェクトをつかむ
標準的なパターンでは、コントローラー上のArea3Dで近くのRigidBody3Dオブジェクトを検出します。グリップを押したときにボディをコントローラーの子にしてフリーズし、グリップを離したときに親ノードを元に戻して、コントローラーの速度を適用して投げます。
物理ベースのつかみ処理の完全な実装(GDScript + C#)については、references/grabbing-objects.mdを参照してください。
5. XR UIインタラクション
VRでUIを表示するには、ControlツリーをSubViewportにレンダリングし、そのテクスチャを3D空間に配置したQuadメッシュに割り当てます。ポインターには、コントローラーからRayCast3Dを飛ばしてQuadに当て、ヒット位置を2Dビューポート座標に変換し、InputEventMouseMotionをSubViewportに送ります。
SubViewportをQuadに割り当てる手順とポインター/レイによるインタラクションについては、references/xr-ui.mdを参照してください。
6. パススルー(複合現実)
対応するヘッドセット(Quest 2+、Pico 4)では、インターフェースのenvironment_blend_modeをXRInterface.XR_ENV_BLEND_MODE_ALPHA_BLENDに設定し、WorldEnvironmentの背景を透明にします。ユーザーには、現実世界の映像に仮想コンテンツが合成されて表示されます。
有効化の手順とQuest固有の注意事項については、references/passthrough.mdを参照してください。
7. Meta Questへのエクスポート
セットアップ
- Android Build Templateをインストールします:Project → Install Android Build Template
- OpenXR Vendorsプラグインをインストールします:Project → Project Settings → Plugins →
Godot OpenXR Vendorsを有効化(またはAssetLibからインストール) - Export → Add → Android
- Androidエクスポートプリセットで次のように設定します:
- XR Features → XR Mode →
OpenXR - Meta XR Features → Hand Tracking / Passthrough(Vendorsプラグインによって追加されます。一致するOpenXR拡張機能を有効にすると表示されます)
- Architectures → arm64 → 有効(QuestはARMです)
- XR Features → XR Mode →
- Metaのストアで必要とされるmin SDKを設定します(執筆時点では29+)
Quest のパフォーマンス設定
| 設定 | 推奨値 |
|---|---|
| レンダラー | Mobile |
| MSAA | 2x または 4x(VR ではアンチエイリアスが必要です) |
| テクスチャ圧縮 | ETC2/ASTC |
| 目標 FPS | 72(Quest 2)または 90(Quest 3) |
重要: VR では安定したフレームレートを維持する必要があります。フレーム落ちは吐き気の原因になります。徹底的にプロファイリングし、ドローコールを少なく抑えてください。
⚠️ Godot 4.7 で変更: 新しいプロジェクト設定
xr/openxr/foveation_eye_trackedとxr/openxr/foveation_with_subsampled_imagesは、どちらもデフォルトでtrueです。フォービエーションレベルが「Disabled」以外の場合、ヘッドセットが対応していれば視線追跡フォービエーションが使用され、さらに Vulkan ではサブサンプル画像が使用され、フォービエーションの効果が高まります。サブサンプル画像は多くのスクリーンスペース機能(例:FXAA、グロー)と互換性がありません。これらの機能が有効な場合、ログ警告とともにサブサンプル画像が自動的に無効になります。いずれかの設定をfalseにすると無効化できます。GH-117868 を参照してください。
8. Godot 4.5+ の XR 機能
Godot 4.5 では、Windows 向け D3D12 OpenXR バックエンド(Quest Link/SteamVR で Vulkan に代わる選択肢)、Mobile Vulkan レンダラーでのフォービエーションレンダリング、Quest/Pico 向け Application SpaceWarp フレーム合成、プラットフォームネイティブのコントローラーメッシュ向け OpenXR Render Models、専用の visionOS プリセットによるウィンドウ表示形式の visionOS エクスポートが追加されます。SpaceWarp を除くすべての機能はコアのプロジェクト設定で利用でき、SpaceWarp には Godot OpenXR Vendors プラグインが必要です。エンジンレベルでのコード変更は不要です。
有効化の手順、GDScript と C# のレンダーモデルのスニペット、機能ごとの注意事項については、references/godot-4-5-features.md を参照してください。
9. Godot 4.6+ の XR 機能
OpenXR 1.1 のサポート(Godot 4.6+)
Godot 4.6 はランタイムに OpenXR 1.1 を要求します。これにより、プロジェクト側で変更を加えることなく 1.1 の機能(昇格されたインタラクションプロファイルやパスなど)が利用可能になり、ランタイムが要求を拒否した場合は 1.0 にフォールバックします。
注: バージョンを強制するには、
xr/openxr/target_api_versionを設定してください(例:1.0.48。デフォルトは空です)。
空間エンティティ — アンカー、平面トラッキング、マーカートラッキング(Godot 4.6+)
Godot 4.6 では、OpenXR の Spatial Entities 拡張機能(実験的 API)が追加されます。セッションをまたいで仮想オブジェクトの位置を保持する 空間アンカー、床・壁・天井の 平面検出、QR コードや画像マーカーの マーカートラッキング が利用できます。XR → OpenXR → Extensions → Spatial Entity で有効にしてください(デフォルトではすべてオフです。デフォルトの RID() コンテキストを使うアンカーでは、Enable Spatial Anchors と Enable Builtin Anchor Detection も有効にする必要があります)。OpenXRSpatialAnchorCapability.create_new_anchor(local_transform, RID()) でアンカーを作成すると、OpenXRAnchorTracker が返されます。そのトラッカーの名前を tracker に指定した XRAnchor3D で表示します。XRSpatialAnchor クラスはありません。
GDScript と C# によるアンカー配置の手順、C# のシングルトン検索、セッションをまたいだアンカーの保持、
create_new_anchor()の Godot 4.7 におけるnextパラメーターについては、references/spatial-entities.md を参照してください。
10. Godot 4.7+ の XR 機能
Godot 4.7 では OpenXR のユーザープレゼンス拡張機能が追加されます。ヘッドセットを装着または取り外したとき(起動時やシャットダウン時を除く)に OpenXRInterface.user_presence_changed(is_user_present: bool) が呼び出されます。また、対応状況の確認と状態の取得には is_user_presence_supported() と is_user_present() を使用します。一般的な用途として、ヘッドセットを外している間はゲームを一時停止し、音声をミュートできます。OpenXRCompositionLayer には eye_visibility(EYE_VISIBILITY_BOTH、_LEFT、_RIGHT)も追加され、一方の目だけにレイヤーを表示できます。また、create_new_anchor() にはベンダーの create-info 構造体を指定するための省略可能な next パラメーターが追加されます。
GDScript と C# によるユーザープレゼンスおよび目の表示範囲の設定例については、references/godot-4-7-features.md を参照してください。アンカーの
nextパラメーターについては、references/spatial-entities.md を参照してください。
11. よくある問題
| 症状 | 原因 | 対処方法 |
|---|---|---|
| ヘッドセットの画面が真っ暗になる | ビューポートで use_xr = true が設定されていない | XR インターフェースを確認した後、_ready() で設定します |
| コントローラーの入力が反応しない | プラットフォームに合わないシグナル名を使用している | プロジェクト設定で OpenXR アクションマップのバインディングを確認します |
| VR でオブジェクトの大きさがおかしい | シーンが実世界の縮尺で作られていない | シーン全体で 1 単位 = 1 メートルを使用します |
| 移動による乗り物酔い | 滑らかな回転 | スナップターン(30°刻み)を使用するか、移動中にビネットを表示します |
| VR で UI が読みづらい | パネルが遠すぎる、または小さすぎる | UI を 1~2m の距離に配置し、解像度 1024 以上の SubViewport を使用します |
| ハンドトラッキングが不安定 | 生の関節データをそのまま使用している | 平滑化を適用します(各フレームで新しい位置に向けて線形補間します) |
| Quest へのエクスポートに失敗する | Android ビルドテンプレートがない、またはアーキテクチャが間違っている | Android Build Template をインストールし、arm64 を有効にして、API レベルを 29 以上に設定します |
12. 実装チェックリスト
- プロジェクト設定で OpenXR が有効になっている
- シーンが
XROrigin3D→XRCamera3D+XRController3Dの階層を使用している - インターフェースの確認後、
get_viewport().use_xr = trueで XR セッションを開始している - ワールドが 1 単位 = 1 メートルの縮尺で作られている
- コントローラー入力で OpenXR アクション名(
trigger_click、grip_clickなど)を使用している - ハンドトラッキングからコントローラートラッキングへのフォールバックがある
- UI パネルが 3D メッシュに描画された SubViewport を使用している
- 移動方法に快適性のオプション(スナップターン、ビネット)が含まれている
- VSync が無効になっている(フレームタイミングは XR ランタイムが処理します)
- Quest へのエクスポートで Mobile レンダラー、arm64 アーキテクチャ、API レベル 29 以上を使用している
- Windows の Quest Link / SteamVR ビルドでは、Vulkan ドライバーに問題がある場合に D3D12 バックエンドを検討する(Godot 4.5+)
- スタンドアロンの Quest/Pico ターゲットでは、Mobile レンダラーの
xr/openxr/foveation_levelを使ってフォービエイテッドレンダリングを有効にする(Godot 4.5+) - Meta Quest / Pico ターゲットのパフォーマンス予算に対して Application SpaceWarp を評価する(Godot 4.5+)
- サポートされている場合、コントローラーのビジュアルに
OpenXRRenderModelManager+xr/openxr/extensions/render_modelを使用する(Godot 4.5+) - visionOS へのエクスポートでは専用の visionOS プリセットを使用する。ウィンドウ表示アプリは 4.7 以降のみ対応(Godot 4.5+)
- 空間アンカーは
OpenXRSpatialAnchorCapabilityで作成し、空間エンティティ拡張機能を有効にしたうえでXRAnchor3Dで表示する(Godot 4.6+) - ヘッドセットの着脱は
OpenXRInterface.user_presence_changedで処理し、ユーザーが離れている間は一時停止またはミュートする(Godot 4.7+) - フォービエイションのデフォルト設定を確認する —
xr/openxr/foveation_eye_trackedとxr/openxr/foveation_with_subsampled_imagesはデフォルトで有効です。FXAA / glow を使用する場合は、サブサンプリング画像を無効にします(Godot 4.7+)