Dual Virtual Joystick for rotate ( left ) and move ( right ) in a First-Person Perspective 3D Room

I built this first-person perspective 3D room with a dual VirtualJoystick (left to rotate and right to move) (https://playground.babylonjs.com/#R7KZRR#1). And it works fine in the player’s initial position, but as soon as you rotate the player, the movement is incorrect. Basically these lines make them rotate and move:

        // Virtual Joystick UP DOWN LEFT RIGHT *** HELP HERE ***
        if(joysticks.rightPuck.isDown){
            player.nextspeed.x = v*0.01*joysticks.xAddPos;
            player.nextspeed.z = -v*0.01*joysticks.yAddPos;        
        }
    
        // Virtual Joystick movement rotation  *** HELP HERE ***
        if(joysticks.leftPuck.isDown){
            player.rotate(BABYLON.Axis.Y, -joysticks.yAddRot*0.01, BABYLON.Space.WORLD);
        }

If I take the vector J ( Joystick ) and the P ( Player ) to calculate the M ( Move ) is not a simple Addition of Vectors but is like to prolongate the coordinates axis J into the direction of P and then calculate the Addition of Vectors. ( See graph )

And I’m not sure how to calculate the correct formula and values to make this work on babylonjs.

Rotate and move also works well with keyboard keys. Arrows to move. The “Z” and “X” to rotate. I appreciate any help. Thank you!

Adding @PolygonalSun our camera guru

After many formulas and calculations I got the answer for the move:

        // Virtual Joystick UP DOWN LEFT RIGHT
        if(joysticks.rightPuck.isDown){
            let joystick_angle = Math.atan2(joysticks.xAddPos,joysticks.yAddPos);
            player.nextspeed.x = v*(camera.getForwardRay().direction.x*Math.cos(joystick_angle)-camera.getForwardRay().direction.z*Math.sin(joystick_angle));
            player.nextspeed.z = v*(camera.getForwardRay().direction.z*Math.cos(joystick_angle)+camera.getForwardRay().direction.x*Math.sin(joystick_angle));    
        }

Here could see working well the joystick: https://playground.babylonjs.com/#R7KZRR#2

1 Like

And for the rotation is quite simple:

        // Virtual Joystick movement rotation
        if(joysticks.leftPuck.isDown){
            let joystick_angle = Math.atan2(joysticks.xAddRot,joysticks.yAddRot);
            if (joystick_angle < 0 ) {
                player.rotate(BABYLON.Axis.Y, -Math.PI / 180, BABYLON.Space.WORLD);
            }else{
                player.rotate(BABYLON.Axis.Y, Math.PI / 180, BABYLON.Space.WORLD);
            }
        }

Here could see working well the joystick rotation: https://playground.babylonjs.com/#R7KZRR#3

2 Likes