Use when working with 2D-specific systems — TileMaps, parallax scrolling, 2D lights and shadows, canvas layers, particles 2D, custom drawing, and 2D meshes in Godot 4.3+
日本語の概要は準備中です。原文の説明を表示しています。
Use when building VR/AR/XR applications — OpenXR setup, XROrigin3D, hand tracking, controllers, passthrough, and Meta Quest deployment 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.
OpenXR (or OpenXR Plugin depending on version)truetrue (for XR shader support)Disabled (the XR runtime controls frame timing)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
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");
}
}
XRController3D nodes (one per hand, child of XROrigin3D) expose buttons via the OpenXR action map. Common buttons: trigger (select_button), grip (grip_button), thumbstick (primary_axis Vector2). Apply thumbstick locomotion velocity to XROrigin3D (not the camera).
See references/controllers-and-input.md for full XRController3D wiring, OpenXR button reference, and thumbstick locomotion recipe.
When the headset supports hand tracking (Quest 2+, Pico 4, some SteamVR setups), XRController3D nodes can be configured to track hand joints. Sample finger positions for gesture detection, or bind to standard select / grip events when the user pinches.
See references/hand-tracking.md for hand-tracking node setup, joint sampling, and gesture-driven interactions.
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 for the full physics-based grabbing implementation (GDScript + C#).
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 for the SubViewport-on-quad recipe and pointer/ray interaction.
For headsets that support it (Quest 2+, Pico 4), set OpenXRInterface.environment_blend_mode = XR_ENVIRONMENT_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 for the full enabling steps and Quest-specific notes.
Godot OpenXR Vendors (or install from AssetLib)OpenXROptional or RequiredOptional (if needed)| 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_trackedandxr/openxr/foveation_with_subsampled_imagesboth default totrue— 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 tofalseto opt out. See GH-117868.
Godot 4.5 adds a D3D12 OpenXR backend on Windows (Quest Link / SteamVR alternative to Vulkan), foveated rendering on the Mobile Vulkan renderer, Application SpaceWarp frame synthesis for Quest/Pico, OpenXR Render Models for platform-native controller meshes, and windowed visionOS export via a dedicated visionOS preset. All are core Project Settings except SpaceWarp, which needs the Godot OpenXR Vendors plugin — no engine-level code changes.
See references/godot-4-5-features.md for enabling steps, GDScript + C# render-model snippets, and per-feature caveats.
Godot 4.6 requests OpenXR 1.1 from the runtime, unlocking 1.1 features (promoted interaction profiles and paths, etc.) without any project-level change, and falls back to 1.0 if the runtime rejects it.
Note: To force a version, set
xr/openxr/target_api_version(e.g.1.0.48; empty by default).
Godot 4.6 adds the OpenXR Spatial Entities extensions (experimental API), enabling:
OpenXRSpatialAnchorCapability, OpenXRAnchorTracker, XRAnchor3D)Basic spatial anchor usage:
# Under XR > OpenXR > Extensions > Spatial Entity enable: Enabled, Enable Spatial Anchors, and
# Enable Builtin Anchor Detection (the default RID() context needs it). All are off by default.
# The capability is a singleton only while OpenXR is enabled; without it this script will not parse.
extends XROrigin3D
func place_anchor_at(local_transform: Transform3D) -> XRAnchor3D:
if not OpenXRSpatialAnchorCapability.is_spatial_anchor_supported():
push_error("Spatial anchors are not supported on this device.")
return null
# The transform is in this XROrigin3D's local space.
var tracker: OpenXRAnchorTracker = OpenXRSpatialAnchorCapability.create_new_anchor(local_transform, RID())
if tracker == null:
return null
# An XRAnchor3D follows the tracker it names; the runtime keeps it on the real-world spot.
var anchor := XRAnchor3D.new()
anchor.tracker = tracker.name
add_child(anchor)
return anchor
// The capability is an engine singleton registered only while OpenXR is running.
public partial class SpatialAnchorManager : XROrigin3D
{
public XRAnchor3D PlaceAnchorAt(Transform3D localTransform)
{
var anchors = Engine.GetSingleton("OpenXRSpatialAnchorCapability") as OpenXRSpatialAnchorCapability;
if (anchors == null || !anchors.IsSpatialAnchorSupported())
{
GD.PushError("Spatial anchors are not supported on this device.");
return null;
}
// The transform is in this XROrigin3D's local space.
OpenXRAnchorTracker tracker = anchors.CreateNewAnchor(localTransform);
if (tracker == null)
return null;
// An XRAnchor3D follows the tracker it names; the runtime keeps it on the real-world spot.
var anchor = new XRAnchor3D { Tracker = tracker.Name };
AddChild(anchor);
return anchor;
}
}
To keep an anchor across sessions, turn on Enable Persistent Anchors, check is_spatial_persistence_supported(), then call persist_anchor(tracker, RID(), callback) and store tracker.uuid with your own data; persisted anchors come back as XRServer.TRACKER_ANCHOR trackers on the next launch. See the OpenXR spatial entities tutorial.
Note: The spatial entities classes arrived in Godot 4.6 and
OpenXRSpatialAnchorCapabilityis still marked experimental — its API may change. There is noXRSpatialAnchorclass; the scene node isXRAnchor3D.
OpenXRInterface exposes the OpenXR user presence extension: the user_presence_changed(is_user_present: bool) signal fires when the user puts on or removes the headset, is_user_presence_supported() reports whether the extension is supported and enabled, and is_user_present() polls the current state (both only return valid values after OpenXR is initialized). Typical use: pause the game and mute audio when the headset comes off.
Note: The signal is not emitted during application startup or shutdown — assume user presence is gained on startup and lost on shutdown.
func _ready() -> void:
var xr_interface: OpenXRInterface = XRServer.find_interface("OpenXR")
if xr_interface and xr_interface.is_user_presence_supported():
xr_interface.user_presence_changed.connect(_on_user_presence_changed)
func _on_user_presence_changed(is_user_present: bool) -> void:
get_tree().paused = not is_user_present
public override void _Ready()
{
var xrInterface = XRServer.FindInterface("OpenXR") as OpenXRInterface;
if (xrInterface != null && xrInterface.IsUserPresenceSupported())
xrInterface.UserPresenceChanged += OnUserPresenceChanged;
}
private void OnUserPresenceChanged(bool isUserPresent)
{
GetTree().Paused = !isUserPresent;
}
OpenXRCompositionLayer gains eye_visibility (EyeVisibility enum: EYE_VISIBILITY_BOTH = 0 default, EYE_VISIBILITY_LEFT = 1, EYE_VISIBILITY_RIGHT = 2) — the eye(s) the composition layer is visible to. Renders a quad/cylinder/equirect layer to one eye only, e.g. for per-eye calibration screens or stereo content authored per eye.
$OpenXRCompositionLayerQuad.eye_visibility = OpenXRCompositionLayer.EYE_VISIBILITY_LEFT
GetNode<OpenXRCompositionLayerQuad>("OpenXRCompositionLayerQuad").EyeVisibility =
OpenXRCompositionLayer.EyeVisibilityEnum.Left;
Note: Not all composition layer types or runtimes support restricting visibility to a single eye.
OpenXRSpatialAnchorCapability.create_new_anchor() gains an optional next parameter — full signature: create_new_anchor(transform: Transform3D, spatial_context: RID = RID(), next: OpenXRStructureBase = null) -> OpenXRAnchorTracker. next must be a valid next object for the XrSpatialAnchorCreateInfoEXT chain, letting vendor-specific create-info structs be appended when creating an anchor. Existing calls are unaffected (compatible change, GH-118128).
Note:
OpenXRSpatialAnchorCapabilityis still marked experimental — the class may change in future versions. Section 9 shows typical anchor placement.
| Symptom | Cause | Fix |
|---|---|---|
| Black screen in headset | use_xr = true not set on viewport | Set in _ready() after checking XR interface |
| Controller input not firing | Wrong signal name for the platform | Check OpenXR action map bindings in Project Settings |
| Objects scale wrong in VR | Scene not built at real-world scale | Use 1 unit = 1 meter throughout the scene |
| Motion sickness from locomotion | Smooth rotation | Use snap turning (30° increments) or add a vignette during movement |
| UI unreadable in VR | Panel too far away or too small | Place UI at 1–2m distance, use SubViewport at 1024+ resolution |
| Hand tracking jittery | Raw joint data used directly | Apply smoothing (lerp toward new position each frame) |
| Export fails on Quest | Missing Android build template or wrong architecture | Install Android Build Template; enable arm64; set API level 29+ |
XROrigin3D → XRCamera3D + XRController3D hierarchyget_viewport().use_xr = true after interface checktrigger_click, grip_click, etc.)xr/openxr/foveation_level on the Mobile renderer for standalone Quest/Pico targets (Godot 4.5+)OpenXRRenderModelManager + xr/openxr/extensions/render_model used for controller visuals where supported (Godot 4.5+)OpenXRSpatialAnchorCapability and shown with XRAnchor3D, with the spatial entities extension enabled (Godot 4.6+)OpenXRInterface.user_presence_changed — pause/mute when the user is away (Godot 4.7+)xr/openxr/foveation_eye_tracked and xr/openxr/foveation_with_subsampled_images are on by default; disable subsampled images if you rely on FXAA/glow (Godot 4.7+)まだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
Use when working with 2D-specific systems — TileMaps, parallax scrolling, 2D lights and shadows, canvas layers, particles 2D, custom drawing, and 2D meshes in Godot 4.3+
日本語の概要は準備中です。原文の説明を表示しています。
Use when working with 3D-specific systems — materials, lighting, shadows, environment, global illumination, fog, LOD, occlusion culling, and decals in Godot 4.3+
日本語の概要は準備中です。原文の説明を表示しています。
Use when building character abilities — Resource-based abilities with cost/cooldown/cast, buffs/debuffs, stat modifiers, gameplay tags, and HUD binding
日本語の概要は準備中です。原文の説明を表示しています。
Use when creating Godot editor plugins — EditorPlugin, @tool scripts, custom inspectors, and dock panels
日本語の概要は準備中です。原文の説明を表示しています。
Use when implementing AI movement — NavigationAgent2D/3D, steering behaviors, behavior trees, and patrol patterns
日本語の概要は準備中です。原文の説明を表示しています。
Use when implementing animations — AnimationPlayer, AnimationTree, blend trees, state machines, sprite animation, and code-driven animation
日本語の概要は準備中です。原文の説明を表示しています。