Develop

Create a Gaze-Targetable UI

Updated: Sep 8, 2026

Overview

As described in UI Interaction Using Gaze, gaze reuses the ray-interactable that an interactable widget spawns for its ray channel. This guide walks through the four editor-side changes that promote an existing UMG widget panel into a gaze target, then verifies the result in Play-in-Editor.
Component chain from the gaze rig through the collision trace to the ray interactable an interactable widget spawns.
The gaze rig traces along the gaze ray, and the interactable widget spawns both the collision surface and the ray interactable that receives the hit.

Prerequisites

Before you start, confirm the following:
  • Gaze is enabled in project settings and the gaze rig is present on the pawn. Follow Getting Started with Gaze Interactions if either is missing. In Project Settings > Plugins > Meta XR - InteractionSDK, verify that Gaze Enabled is on. The Allow Gaze By Default and Gaze Fallback Behavior fields are hidden until it is.
    Interaction SDK project settings with Gaze Enabled checked, revealing Allow Gaze By Default and Gaze Fallback Behavior.
  • The Epic OpenXR plugin is enabled, and Project Settings > Plugins > Meta XR > General > XR API is set to Epic Native OpenXR.
  • The widget panel you want to target is already displayed in the world using the interactable widget workflow described in Interactable Widgets.

Add the Interactable Widget

Choose one of the following approaches, based on how the panel is authored:
  • Drop an ISDK Interactable Widget actor (AIsdkInteractableWidget) into the level from the Place Actors panel. Set its Widget Class to your UUserWidget subclass. The actor’s root is a UIsdkInteractableWidgetComponent, so all of the properties in the following steps live directly on the actor.
    Details panel showing the Widget Class property of the interactable widget set to IsdkSampleUIWidget.
  • On an existing actor, use Add Component to attach a UIsdkInteractableWidgetComponent and set its Widget Class in the Details panel.
    Components panel of the IsdkSampleUI actor with IsdkInteractableWidget attached under Root.
The component spawns a child UWidgetComponent at runtime that renders your UMG widget and supplies the collision surface the gaze trace hits.

Confirm Create Ray Interactable Is Enabled

Select the interactable widget and, in the Details panel, verify that Create Ray Interactable (the bCreateRayInteractable property) is checked. This is the default. Gaze routes through the spawned UIsdkRayInteractable, so leaving this off produces no gaze hits regardless of the other settings.
Details panel showing the Create Ray Interactable checkbox checked under Interactable, Ray Interactable.

Set the Gaze Policy

On the interactable widget, locate Gaze Policy under **Interaction SDK
Interactable
Ray Interactable**. The property has three values:
Details panel showing Gaze Policy set to Use Plugin Setting under Interactable, Ray Interactable.
ValueBehavior
Use Plugin Setting
Defers to the project-wide Allow Gaze By Default setting.
Allow
Forces this widget to accept gaze regardless of the project default.
Disallow
Blocks gaze on this widget even when the project default allows it.
The property is declared with its default value on the component:
EIsdkGazePolicy GazePolicy = EIsdkGazePolicy::UsePluginSetting;
At BeginPlay, the component copies this value onto the ray interactable it spawns, so the widget-level policy is what the gaze rig sees at runtime. Use Allow when the project default is off but this panel should still respond to gaze. Use UsePluginSetting for panels that follow the project-wide default.

Confirm the Collider Blocks the Gaze Trace Channel

The gaze rig traces along its ray using the collision channel on UIsdkGazeTargetingComponent::GazeCollisionChannel, which defaults to ECC_Visibility. Only colliders set to Block on that channel produce a hit; Overlap and Ignore are skipped by the multi-trace.
The UWidgetComponent that the interactable widget spawns provides the collision by default. If you replaced the collision setup or nested the widget under a parent that overrides collision responses, open the widget component in the Details panel and set its response to Visibility back to Block.
Collision Presets with the Visibility trace response set to Block and Collision Enabled set to Query Only.

Verify in Play-in-Editor

Launch Play-in-Editor on the desktop to iterate without putting the headset on. The rig auto-selects UIsdkPieMouseGazeDataSource at BeginPlay, which deprojects the mouse cursor into a world-space gaze ray. Move the cursor over the panel and confirm the widget reports a hover state.
Play-in-Editor view of the sample UMG panel rendered in world space.
Select is not driven by the mouse. In PIE, IsEyeTrackingAvailable_Implementation returns false, and select still flows through the hand rig’s InputActions->SelectAction (system pinch). To confirm the select path end-to-end, trigger a pinch from the paired headset.
If the panel does not report a hover, add a UIsdkWidgetRegionDebugComponent to the actor via Add Component. With bAutoWireWidget at its default of true, the component binds to the owner’s first UWidgetComponent at BeginPlay and draws wireframe boxes around each interactable region, with the whole-panel region in a distinct color.
Widget region debug wireframes outlining each clickable sub-widget of the sample UMG panel in red.
Use the wireframe to isolate the failure. A missing wireframe means the debug component cannot find the widget. A wireframe drawn with no hover under the cursor points at the collision channel or the gaze policy.

Learn more

Now that you know how to make a widget respond to gaze, continue on to the following guides: