# WebXR Multiplayer with hand tracking does not work correctly in left handed scene

**URL:** <https://forum.babylonjs.com/t/webxr-multiplayer-with-hand-tracking-does-not-work-correctly-in-left-handed-scene/58079>\
**Category:** Questions\
**Tags:** webxr\
**Created:** [April 26, 2025, 10:19am UTC](https://forum.babylonjs.com/t/webxr-multiplayer-with-hand-tracking-does-not-work-correctly-in-left-handed-scene/58079 "2025-04-26T10:19:56Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![hardik](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/hardik/32/41732_2.png) [@hardik](https://forum.babylonjs.com/u/hardik)\
**Post date:** [April 26, 2025, 10:19am UTC](https://forum.babylonjs.com/t/webxr-multiplayer-with-hand-tracking-does-not-work-correctly-in-left-handed-scene/58079/1 "2025-04-26T10:19:56Z")

</div>

Hi everyone,

I’m making a multiplayer webxr experience using babylonjs (scene is using left handed system). I’m using Hand tracking feature instead of the motion controllers. For remote players, I’m spawning a cube for the head, and for the hands I’m spawning the default webxr hands provided by babylonjs. I noticed that if i use **scene.useRightHandedSystem = true;** the webxr data comes correctly and the remote hands syncs perfectly. But when i use in left handed system..the custom hand seems off/skewed. Any idea what’s happening? What am i missing here? Attaching a screenshot and 2 videos for reference.

  

Code sample:

```auto
      xr.baseExperience.onStateChangedObservable.add(async (newState) => {
        if (newState === WebXRState.IN_XR) {
          const testPlayer = new TestPlayer("test", this.scene!);
          await testPlayer.spawn();

          sessionManager.onXRFrameObservable.add((xrFrame) => {
            const pose = xrFrame.getViewerPose(sessionManager.referenceSpace);
            for (const input of xr.input.controllers) {
              const xrHand = input.inputSource.hand;
              if (!xrHand) return;
              for (const joint of xrHand.keys()) {
                const space = xrHand.get(joint)!;
                const jointPose = xrFrame.getJointPose?.(space, sessionManager.referenceSpace);
                if (!jointPose) return;
                const position = jointPose.transform.position;
                const orientation = jointPose.transform.orientation;

                const node = testPlayer.tNodes.get(`${joint}_${input.inputSource.handedness === "right" ? "R" : "L"}`);
                if (!node) return;
                node.setAbsolutePosition(new Vector3(position.x, position.y, -position.z));
                node.rotationQuaternion = new Quaternion(orientation.x, orientation.y, -orientation.z, -orientation.w);
              }
            }
          });
        }
      });

```

 ![Screenshot 2025-04-26 153856](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/3X/1/f/1f701bab43d5ac96af62069292b274f8833fa756.jpeg)

---

<div class="post-metadata">

**Author:** ![Deltakosh](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/deltakosh/32/26635_2.png) [@Deltakosh](https://forum.babylonjs.com/u/Deltakosh)\
**Post date:** [April 28, 2025, 2:31pm UTC](https://forum.babylonjs.com/t/webxr-multiplayer-with-hand-tracking-does-not-work-correctly-in-left-handed-scene/58079/2 "2025-04-28T14:31:10Z")

</div>

cc @RaananW

---

<div class="post-metadata">

**Author:** ![RaananW](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/raananw/32/28955_2.png) [@RaananW](https://forum.babylonjs.com/u/RaananW)\
**Post date:** [April 28, 2025, 2:35pm UTC](https://forum.babylonjs.com/t/webxr-multiplayer-with-hand-tracking-does-not-work-correctly-in-left-handed-scene/58079/3 "2025-04-28T14:35:02Z")

</div>

This happens because the webxr data is right-handed. Babylon is converting the data to be able to show it in left-handed systems. This is why we abstract the WebXT hand concept in our own class. You can use the webXXR hands feature to achieve that, or run the same conversion we are running to support LHS

---

<div class="post-metadata">

**Author:** ![hardik](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/hardik/32/41732_2.png) [@hardik](https://forum.babylonjs.com/u/hardik)\
**Post date:** [April 30, 2025, 7:06am UTC](https://forum.babylonjs.com/t/webxr-multiplayer-with-hand-tracking-does-not-work-correctly-in-left-handed-scene/58079/4 "2025-04-30T07:06:12Z")

</div>

I already did the conversion. I’ve attached the code that I’m currently using. After doing the conversion only, the hands look like this.

---

<div class="post-metadata">

**Author:** ![RaananW](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/raananw/32/28955_2.png) [@RaananW](https://forum.babylonjs.com/u/RaananW)\
**Post date:** [April 30, 2025, 10:22am UTC](https://forum.babylonjs.com/t/webxr-multiplayer-with-hand-tracking-does-not-work-correctly-in-left-handed-scene/58079/5 "2025-04-30T10:22:08Z")

</div>

Are these our hand meshes? There is one more transformation you will need to do (and this is why I still recommend using our implementation for simplicity 🙂 ). When loading the mesh in LHS you will need to transform the 2nd mesh received by the import function:

```auto
if (!scene.useRightHandedSystem) {
   handGLB.meshes[1].rotate(Axis.Y, Math.PI);
}

```

We also link transform nodes to the bones while keeping the joint meshes independent. And keep them both updated on each frame.
