Develop

Custom Hand and Controller Meshes

Updated: Apr 15, 2026
Interaction SDK provides a generic set of Skeletal Meshes that can be used to represent hands and controllers in your project. For situations where you need to use custom meshes, you can assign your own meshes in the hand and controller rig components on your Pawn. This enables you to have the hands visible to the player match their character, making the experience more immersive.
Custom Hand Mesh with Interaction SDKShown above: The default Unreal XR hand re-bound to the OpenXR hand skeleton is being used with Interaction SDK.
Note: This guide assumes knowledge of how to model your custom mesh, bind it to a skeleton, and export it into Unreal.

Custom mesh requirements

Your custom hand or controller mesh must have an identical skeleton to the default Interaction SDK hand or controller mesh it is replacing. While the skeletons are not available as a download, they can be exported from within Unreal Editor to an FBX file which can be used in your 3D application of choice to skin your custom mesh.

Hand Skeleton

Hand Skeleton HierarchyHand Skeleton

Controller Skeleton

Controller Skeleton HierarchyController Skeleton

Exporting the default skeleton

To export the default hand or controller skeleton from Unreal Editor for use as a reference in your 3D application:
  1. Open the Content Browser and navigate to the default Skeletal Mesh asset you want to export. The default hand meshes are located at /OculusInteraction/Models/Hands/ (SK_OpenXRHand_Left or SK_OpenXRHand_Right). The default controller meshes are located at /OculusInteraction/Models/Controllers/MetaQuestPro/ (SK_MetaQuestPro_Left or SK_MetaQuestPro_Right).
  2. Right-click the Skeletal Mesh asset and select Asset Actions > Export.
  3. In the export dialog, choose FBX as the file format and select a save location.
  4. Click Save to export the FBX file. You can then import this file into your 3D application to use as a skeleton reference when skinning your custom mesh.
Note: Your custom mesh must use an identical bone hierarchy and bone names to the exported skeleton. Mismatched bone names or hierarchy differences prevent the mesh from binding correctly.

Applying a custom hand mesh

The hand mesh displayed by Interaction SDK is determined by the Hand Visuals Component of the hand rigs on the Pawn. There are four hand meshes that Interaction SDK displays depending on the situation. If you want to display your custom mesh for each of these hand types, you must assign the mesh to the visuals component for each of the corresponding hand types. In addition, you must set the mesh for each hand, left and right.
Note: The hand mesh for the controller hand types is determined by the Controller Visuals Component of the controller rigs on the Pawn as opposed to the Hand Visuals Component of the hand rigs.
Hand TypeDescriptionMesh Property
Tracked Hand
This is the hand displayed when using hands only and the raw hand tracking data is being used for the hand’s joint location and orientations.
IsdkHandRigComponent > Interaction SDK > Hand Visuals Component > Interaction SDK > Tracked Hand Visual > Mesh > Skeletal Asset > Skeletal Mesh
Synthetic Hand
This is the hand displayed when using hands only and the joint location or orientations have been altered by an interaction.
IsdkHandRigComponent > Interaction SDK > Hand Visuals Component > Interaction SDK > Synthetic Hand Visual > Mesh > Skeletal Asset > Skeletal Mesh
Animated Controller Hand
This is the hand displayed when using hands and controllers and the hand’s pose is being driven by animation data from the Animation Blueprint.
IsdkControllerRigComponent > Interaction SDK > Controller Visuals Component > Interaction SDK > Animated Hand Mesh Component > Mesh
Poseable Controller Hand
This is the hand displayed when using hands and controllers and the hand’s pose is being driven by runtime tracking data.
IsdkControllerRigComponent > Interaction SDK > Controller Visuals Component > Interaction SDK > Poseable Hand Mesh Component > Mesh > Skeletal Asset > Skeletal Mesh

Assigning a custom hand mesh

To replace the default hand mesh with your custom mesh for a given hand type:
  1. In the Content Browser, double-click your Pawn Blueprint to open it for editing.
  2. In the Components panel, select the IsdkHandRigComponent for the hand you want to customize (left or right).
  3. In the Details panel, expand Interaction SDK > Hand Visuals Component > Interaction SDK to locate the hand type you want to replace. For example, expand Tracked Hand Visual to replace the tracked hand mesh.
  4. Under the target hand type, expand Mesh > Skeletal Asset and set the Skeletal Mesh property to your custom Skeletal Mesh asset.
  5. Repeat the previous step for each additional hand type you want to replace (Tracked Hand, Synthetic Hand, or both).
  6. For the controller-driven hand types (Animated Controller Hand and Poseable Controller Hand), select the IsdkControllerRigComponent instead. In the Details panel, expand Interaction SDK > Controller Visuals Component > Interaction SDK to locate the controller hand visuals.
  7. Set the mesh on the Animated Hand Mesh Component or Poseable Hand Mesh Component as needed, following the same property expansion pattern used in the previous steps.
  8. Repeat the entire process for the other hand (left or right) using the corresponding rig component.
  9. Compile and save the Blueprint.

Applying a custom controller mesh

The controller mesh displayed by Interaction SDK is determined by the Controller Visuals Component of the controller rigs on the Pawn. You must set your custom mesh for both the left and right controllers using the following property:
IsdkControllerRigComponent > Interaction SDK > Controller Visuals Component > Interaction SDK > Controller Mesh Component > Mesh
Controller Mesh Property

Assigning a custom controller mesh

To replace the default controller mesh with your custom mesh:
  1. In the Content Browser, double-click your Pawn Blueprint to open it for editing.
  2. In the Components panel, select the IsdkControllerRigComponent for the left controller.
  3. In the Details panel, expand Interaction SDK > Controller Visuals Component > Interaction SDK > Controller Mesh Component and set the Mesh property to your custom controller Skeletal Mesh asset.
  4. Repeat the previous steps for the right controller by selecting the corresponding IsdkControllerRigComponent and assigning the right-hand version of your custom mesh.
  5. Compile and save the Blueprint.

Verifying your custom mesh

After assigning your custom mesh, verify that it displays and animates correctly:
  1. In the Level Editor toolbar, click Play (VR Preview if using a headset, or Selected Viewport for desktop testing) to start a play session.
  2. Confirm that your custom hand mesh appears in place of the default mesh when using hand tracking. Move your hands to verify that joints track correctly and the mesh deforms as expected.
  3. If you replaced controller hand meshes (Animated Controller Hand or Poseable Controller Hand), hold a controller and verify the hand mesh transitions between the tracked, synthetic, animated, and poseable states as you interact with objects.
  4. If you replaced the controller model mesh (Controller Mesh Component), verify the controller model displays for both the left and right controllers.
  5. To test on device, package or deploy your project to a Meta Quest headset and confirm the custom meshes appear and animate correctly at runtime.

Troubleshooting

Mesh does not appear

Symptom: After assigning a custom mesh, the hand or controller is invisible during play.
Solution: Verify that the Skeletal Mesh asset is assigned to the correct property for the hand type you are testing. Each hand type (Tracked, Synthetic, Animated Controller, Poseable Controller) has its own mesh property. Also confirm the mesh is assigned for both the left and right hands or controllers.

Bones do not animate or deform correctly

Symptom: The custom mesh appears but does not follow hand tracking, or joints bend incorrectly.
Solution: Ensure your custom mesh skeleton has an identical bone hierarchy and bone naming to the default Interaction SDK skeleton. Export the default skeleton as described in Exporting the default skeleton and compare it against your custom skeleton in your 3D application. Every bone must match in name, hierarchy order, and parent-child relationships.

Mesh appears in the wrong position or orientation

Symptom: The custom mesh renders but is offset, rotated, or scaled incorrectly relative to the hand or controller.
Solution: Verify that your custom mesh was authored at the same scale and orientation as the default mesh. The root bone transform of your mesh should match the root bone transform of the default Interaction SDK skeleton. Re-export with corrected transforms if needed.

Learn more

To learn more about using Interaction SDK in your project, see the following guides: