Skip to content
Development
Skill

/xr-development

Use when building VR/AR/XR applications — OpenXR setup, XROrigin3D, hand tracking, controllers, passthrough, and Meta Quest deployment in Godot 4.3+

From plugin
godot-prompter
90361 skills9 agents1 hook

Claude Code

$ npx -y skills add jame581/GodotPrompter --skill xr-development --agent claude-code

SKILL.md

xr-development.SKILL.md
name: xr-development
description: Use when building VR/AR/XR applications — OpenXR setup, XROrigin3D, hand tracking, controllers, passthrough, and Meta Quest deployment in Godot 4.3+

XR Development in Godot 4.3+

All examples target Godot 4.3+ with no deprecated APIs. GDScript is shown first, then C#.

> **Related skills:** **3d-essentials** for 3D rendering and environment, **physics-system** for 3D physics interactions, **input-handling** for non-XR input patterns, **export-pipeline** for platform exports.

---

1. XR Setup

Enabling OpenXR

1. OpenXR is built into the engine — there is no plugin to enable. 2. **Project Settings → XR → OpenXR → Enabled** → `true` 3. **Project Settings → XR → Shaders → Enabled** → `true` (for XR shader support) 4. **Rendering:**

  • Use **Forward+** or **Mobile** renderer (Compatibility also works for simpler scenes)
  • Set **Project Settings → Display → Window → VSync Mode** to `Disabled` (the XR runtime controls frame timing)

Core Scene Structure

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

Starting XR Session

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. Controllers and Input

`XRController3D` nodes (one per hand, child of `XROrigin3D`) expose buttons via the OpenXR action map. Default action map names: trigger (`trigger` float, `trigger_click`), grip (`grip`, `grip_click`), thumbstick (`primary` Vector2, `primary_click`). Apply thumbstick locomotion velocity to `XROrigin3D` (not the camera).

> See [references/controllers-and-input.md](references/controllers-and-input.md) for full XRController3D wiring, OpenXR button reference, and thumbstick locomotion recipe.

---

3. Hand Tracking

When the headset supports hand tracking (Quest 2+, Pico 4, some SteamVR setups), the runtime publishes `XRHandTracker`s (`/user/hand_tracker/left` / `right`); an `XRHandModifier3D` poses a hand skeleton from them, and `XRController3D` still gets select / grip actions through the hand interaction profiles. Sample finger joints for gesture detection.

> See [references/hand-tracking.md](references/hand-tracking.md) for hand-tracking node setup, joint sampling, and gesture-driven interactions.

---

4. Grabbing Objects

Standard pattern: an `Area3D` on the controller detects nearby `RigidBody3D` objects; on grip-press, parent the body to the controller and freeze it; on grip-release, restore the parent and apply the controller's velocity to launch.

> See [references/grabbing-objects.md](references/grabbing-objects.md) for the full physics-based grabbing implementation (GDScript + C#).

---

5. XR UI Interaction

For UI in VR, render a `Control` tree to a `SubViewport`, map its texture onto a `Quad` mesh placed in 3D space. Pointer: a `RayCast3D` from the controller hits the quad, the hit position is converted back to 2D viewport coords, an `InputEventMouseMotion` is forwarded into the SubViewport.

> See [references/xr-ui.md](references/xr-ui.md) for the SubViewport-on-quad recipe and pointer/ray interaction.

---

6. Passthrough (Mixed Reality)

For headsets that support it (Quest 2+, Pico 4), set the interface's `environment_blend_mode` to `XRInterface.XR_ENV_BLEND_MODE_ALPHA_BLEND` and clear the `WorldEnvironment` background to transparent. The user sees the real world with virtual content composited on top.

> See [references/passthrough.md](references/passthrough.md) for the full enabling steps and Quest-specific notes.

---

7. Meta Quest Export

Setup

1. Install Android Build Template: **Project → Install Android Build Template** 2. Install OpenXR Vendors plugin: **Project → Project Settings → Plugins → Enable `Godot OpenXR Vendors`** (or install from AssetLib) 3. **Export → Add → Android** 4. In the Android export preset:

  • **XR Features → XR Mode** → `OpenXR`
  • **Meta XR Features → Hand Tracking** / **Passthrough** (added by the vendors plugin; shown once the matching OpenXR extension is enabled)
  • **Architectures → arm64** → enabled (Quest is ARM)

5. Set the min SDK to what Meta's store requires (29+ when this was written)

Performance Settings for Quest

| Setting | Recommended Value | |---------|-------------------| | Renderer | Mobile | | MSAA | 2x or 4x (VR needs antialiasing) | | Texture Compression | ETC2/ASTC | | Target FPS | 72 (Quest 2) or 90 (Quest 3) |

> **Critical:** VR must maintain consistent frame rate. Dropped frames cause nausea. Profile aggressively and keep draw calls low.

> ⚠️ **Changed in Godot 4.7:** New project settings `xr/openxr/foveation_eye_tracked` and `xr/openxr/foveation_with_subsampled_images` both default to `true` — when the foveation level is not "Disabled", eye-tracked foveation is used where the headset supports it, and subsampled images are used on Vulkan for a bigger foveation win. Subsampled images are incompatible with many screen-space features (e.g., FXAA, glow); if any are enabled, subsampled images are automatically disabled with a log warning. Set either setting to `false`

Read more
@jame581
Ships withgodot-prompter

Agentic skills framework for Godot 4.x game development. Gives AI coding agents domain-specific expertise for GDScript and C# projects.

90361 skills9 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
903
Star history of jame581/GodotPrompter on GitHub, a chart by star-history.com

Other skills on godot-prompter.

2d-essentials

2d-essentials

Use when working with 2D-specific systems — TileMaps, parallax scrolling, 2D lights and shadows, canvas layers, particles 2D,…

3d-essentials

3d-essentials

Use when working with 3D-specific systems — materials, lighting, shadows, environment, global illumination, fog, LOD, occlusion…

ability-system

ability-system

Use when building character abilities — Resource-based abilities with cost/cooldown/cast, buffs/debuffs, stat modifiers, gameplay…

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills11d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc12d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react2d252k
@facebook@facebookInstall Skill

Questions about xr-development.

Which coding agents can use xr-development?
xr-development installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.