I have the following code that is run on every frame:
const yRotationPerFrame =
(scaleSensitivity(leftStick.x) * framePeriod) / 15
const forwardVelocity = scaleSensitivity(leftStick.y, 5)
const sidewaysVelocity = -scaleSensitivity(rightStick.x, 5)
// const elevationAngle = -rightStick.y / 40
// camera.rotation.x = elevationAngle
camera.rotation.y -= yRotationPerFrame
forwardVector.set(0, 0, forwardVelocity)
sideVector.set(sidewaysVelocity, 0, 0)
direction
.subVectors(forwardVector, sideVector)
.applyEuler(camera.rotation)
setLinearVelocity({ x: direction.x, y: velocity.y, z: direction.z })
when I uncomment the line camera.rotation.x = elevationAngle
, it kind of works but only for the meanwhile when there is no y rotation.
I tried with camera.rotation.x = elevationAngle
but I was expecting it would work regardless of the camera.rotation.y
number. Unfortunately that is not the case...
Here is the solution that I came up with and that solved the problem:
const forwardVelocity = scaleSensitivity(leftStick.y, 5)
const sidewaysVelocity = -scaleSensitivity(rightStick.x, 5)
const elevationAngle = -rightStick.y / 40
// Get the RigidBody's current rotation
const rigidBodyRotation = ref.current.rotation()
forwardVector.set(0, 0, forwardVelocity)
sideVector.set(sidewaysVelocity, 0, 0)
direction
.subVectors(forwardVector, sideVector)
.applyQuaternion(rigidBodyRotation)
// Create a quaternion for the elevation angle (pitch)
const elevationQuaternion = new Quaternion().setFromAxisAngle(
new Vector3(1, 0, 0), // Rotate around the X-axis (pitch)
elevationAngle
)
// Combine the RigidBody's rotation with the elevation quaternion
const combinedRotation = rigidBodyRotation.clone()
.multiply(elevationQuaternion)
// Set the camera's rotation to the combined quaternion
camera.rotation.setFromQuaternion(combinedRotation)
// Set the angular velocity directly
ref.current.setAngularVelocity({x: 0, y: -scaleSensitivity(leftStick.x, 25), z:0})
ref.current.setLinearVelocity({ x: direction.x, y: velocity.y, z: direction.z })