Getting Started with Controller Input and Tracking
Updated: Apr 14, 2026
Controller input and tracking is the most basic input format for any XR application. It enables users to perform complex interactions with the virtual world using a familiar interface. This guide shows you how to get basic controller input and tracking up and running in your Unreal Engine project. It then demonstrates how to respond to controller input events, access tracking data, and provide haptic feedback.
When you finish this guide, you should be able to:
- Add Meta Quest controller handling to an Unreal Engine project.
- Receive user input through a controller’s triggers.
- Receive input when the user presses a controller’s thumbstick.
- Provide haptic feedback.
- Receive position and rotation information of a controller (six degrees of freedom, or 6DOF).
This guide relies on the Meta XR plugin for Unreal Engine. Make sure you have it installed before continuing. For installation instructions, see
Installing the Meta XR Plugin.
To begin adding your own functionality, you need to create and configure some custom framework classes and tell the application to use them instead of the defaults.
In the Content Drawer, right-click in an empty space and select Blueprint Class. In the class picker dialog, search for and select Game Mode Base as the parent class. Click Select to create the Blueprint. Name the new asset appropriately for your use case. In this example, it is called ControllerGameMode.
In the Content Drawer, create a new Blueprint Class asset using Pawn as the parent class. Name the new asset appropriately for your use case. In this example, it is called ControllerPawn.
In the Window menu, select World Settings. Assign your new Game Mode asset to the GameMode Override property to use your Game Mode when you run the application.
In the Content Drawer, double-click the Game Mode asset to open it for editing. In the Blueprint Editor toolbar, click Class Defaults if it is not already selected. Assign your new Pawn asset to the Default Pawn Class property to force your Pawn class to be used with your Game Mode.
To accept input from the user, you need to set up mappings that pass the hardware inputs to your framework.
In the Content Drawer, add a new Input Action asset. This will be for the A button press on the right controller so name it appropriately. In this example, it is called XR_R_A_InputAction.
- Repeat this process for all additional inputs you want to have access to. At minimum, you need Input Actions for:
- A button press (Value Type:
Digital (bool)) - Grip Axis (Value Type:
Axis1D (float)) - Right Thumbstick (Value Type:
Axis2D (Vector2D))
If you add an Input Action for an axis input, double-click the asset and set the Value Type property to the correct type.
In the Content Drawer, add a new Input Mapping Context asset and name it appropriately. In this example, it is called XRInputMappingContext.
Double-click the Input Mapping Context asset to edit it and add entries to the Mappings array for each Input Action, associating each with the corresponding input. For the thumbstick, map your thumbstick Input Action to OculusTouch Right Thumbstick X-Axis and OculusTouch Right Thumbstick Y-Axis.
The custom Pawn class is where the controller tracking takes place. You need to add specialized components to this class to access the controller data and visualize the controllers in the world.
- In the Content Drawer, double-click the Pawn asset to open it for editing.
In the Components panel, add a new Motion Controller component under the DefaultSceneRoot component. Name the new component LeftMotionController.
- With the LeftMotionController component selected, set the Motion Source property to Left in the Details panel.
In the Components panel, add a new Motion Controller component under the DefaultSceneRoot component. Name the new component RightMotionController.
- With the RightMotionController component selected, set the Motion Source property to Right in the Details panel.
In the Components panel, add a new OculusXRController component under the LeftMotionController component. Name the component LeftOculusXRController.
- With the LeftOculusXRController component selected, set the Skeleton Type property to Left in the Details panel.
In the Components panel, add a new OculusXRController component under the RightMotionController component. Name the component RightOculusXRController.
- With the RightOculusXRController component selected, set the Skeleton Type property to Right in the Details panel.
In the Components panel, add a new Camera component under the DefaultSceneRoot component. Name the component VRCamera.
For tracking and input to work, you need to set up the tracking space and associate the Input Mapping Context you created previously with the player.
In the Event Graph, right-click by the Begin Play event and choose Is Head Mounted Display Enabled.
Drag off the output pin of the Is Head Mounted Display Enabled node and choose Branch.
- Drag a connection from the output exec pin of the Begin Play event to the input exec pin of the Branch node.
Drag off the output exec pin of the Branch node and choose Set Tracking Origin.
On the Set Tracking Origin function, set the Origin pin value to Local Floor.
Note: Local Floor sets the tracking origin at floor level beneath the user’s initial position. This is the recommended tracking origin for controller-based XR applications because it provides a consistent reference point that accounts for the user’s physical height.
Right-click after the Set Tracking Origin function and choose Get Player Controller.
Drag off the output pin of the Get Player Controller node and choose Get EnhancedInputLocalPlayerSubsystem.
Drag off the Enhanced Input Local Player Subsystem node and choose Add Mapping Context.
On the Add Mapping Context function, set the Mapping Context pin value to reference the Input Mapping Context asset you created previously.
- Drag a connection from the output exec pin of the Set Tracking Origin function to the input exec pin of the Add Mapping Context function.
The completed Begin Play event network should look like this:
Now that the Input Mapping Context is registered with the player, you can respond to individual Input Actions in the Event Graph using Enhanced Input Action nodes. This section demonstrates how to respond to the A button press and read thumbstick values.
- In the Event Graph, right-click in an empty space and choose Enhanced Input Action. In the action list, select the A button Input Action you created earlier (for example, XR_R_A_InputAction).
- Drag off the Triggered exec pin of the Enhanced Input Action node. This pin fires each frame the action is active. Connect it to a Print String node and enter a test message such as
A Button Pressed. - Compile and save your Pawn Blueprint, then run the level on your device. Press the A button on the right controller and confirm the message appears on screen.
- Add another Enhanced Input Action node and select your thumbstick Input Action.
- Drag off the Action Value output pin (a
Vector2D) and choose Break Vector 2D to split it into X and Y components. - Connect the X and Y values to Print String nodes or use them to drive movement logic. The X axis represents left/right deflection and the Y axis represents forward/back deflection, each ranging from
-1.0 to 1.0.
The same pattern applies to the Grip Axis input. Add an Enhanced Input Action node for your grip Input Action and use the Action Value float output to read the grip squeeze amount (0.0 to 1.0).
Access and Store Controller Tracking Data
Use the Tick event to access and store the controller tracking data each frame. You can use the stored data in other locations without having to execute the logic to access it over and over, which saves time during development and makes it more efficient at runtime.
Note: The Get Motion Controller Data node is deprecated in Unreal Engine 5.7 and later. If you are using UE 5.7+, use the Get Motion Controller State node instead, which has been available since UE 5.5. The workflow steps below remain the same; only the node name differs.
Drag the RightOculusXRController component from the Components section of the My Blueprint panel to the Event Graph next to the Tick event. Select Get RightOculusXRController.
Drag off the output pin of the RightOculusXRController node and choose Get Motion Controller Data.
On the Get Motion Controller Data function, set the Hand pin value to Right.
- Drag a connection from the output exec pin of the Tick event to the input exec pin of the Get Motion Controller Data function.
Drag off the Motion Controller Data output pin of the Get Motion Controller Data function and choose Promote to Variable.
In the Variables section of the My Blueprint panel, rename the new variable to Right Motion Controller Data.
Drag off the output pin of the Set node and search for Break XRMotionControllerData. If you don’t see it in the context menu, uncheck Context Sensitive at the top of the menu and search again.
- Click the down arrow on the Break XRMotionControllerData node to expose all of the output pins.
Drag off the output exec pin of the Set node and choose Print String.
Drag a connection from the Aim Position output pin of the Break XRMotionControllerData node to the In String input pin of the Print String function.
- In the Blueprint Editor toolbar, click the Compile button to compile your Pawn class. Click the Save button to save the asset.
- Run the level on your device to view the controller position printed to the screen.
The controller position is output to the screen as you move the controller around:
Note: To track the left controller as well, repeat the same process using the LeftOculusXRController component and set the Hand pin value to Left.
You can trigger haptic feedback on Meta Quest controllers to provide tactile responses to user actions. The simplest approach uses the Set Haptics by Value node, which lets you specify vibration frequency and amplitude directly.
- In the Event Graph, after the node where you want to trigger feedback (for example, the Triggered pin of your A button Enhanced Input Action), right-click and search for Set Haptics by Value.
- Set the Frequency and Amplitude values between
0.0 and 1.0. A frequency of 0.5 and amplitude of 0.5 produces a moderate vibration. - Set the Hand parameter to the target controller (Left or Right).
- Compile and run on your device. Press the A button to confirm you feel the haptic pulse.
Now that you know how to get started with the feature, continue on to the following guides: