# [Solved] Camera Rotation for First-Person Controls

Hey all,

I’m attempting to make a first-person camera and control its rotation using the mouse. This works fine for the most part but I’m having an issue when the camera turns to the side and looks up or down. It looks like it changes the roll/z-axis instead of the X axis.

If you look at that example and slowly move the mouse up/down or left/right you can see it works fine, but if you move right and then up, you can see that it moves diagonally, and changes the roll if you look directly right.
I feel like I’m missing something really stupid here. Any ideas?

1 Like

Issue fixed. I had to collect all the rotation data and create a quaternion from the euler of the rotation values. Or something like that.

onMouseMove(e) {
const movementX = e.movementX || e.mozMovementX || e.webkitMovementX || 0;
const movementY = e.movementY || e.mozMovementY || e.webkitMovementY || 0;

this._motion.rotation.y += -movementX * Math.PI / 180;
this._motion.rotation.x += -movementY * Math.PI / 180;

const euler = new THREE.Euler(0, 0, 0, 'YXZ');
euler.x = this._motion.rotation.x;
euler.y = this._motion.rotation.y;
this.camera.quaternion.setFromEuler(euler);

this.camera.rotation.x = Math.min(Math.max(this.camera.rotation.x, -1.0472), 1.0472);
}

Have you seen PointerLockControls? It’s used in the following example. Maybe you can use the code from this class for your own app.

https://threejs.org/examples/misc_controls_pointerlock.html

can you tell me what is this._motion.rotation.y and this._motion.rotation.x. Thank you

Do you know, what is those this._motion ? @Alok_Sharma_as

I know this is old, but someone might need this. I’ve found this plugin and it’s totally awesome: GitHub - yomotsu/camera-controls at master

Check this out for first-person control example: =^.^=

…And third-person example: =^.^=

Just to clarify, what made your code sample work is because you created an Euler angle with the YXZ order and applied that to the camera.quaternion. (as opposed to the default XYZ order used by the camera.rotation of your codepen, hence why it did not behave as expected when you tweak the camera Euler angle directly)

Also, no need for a this._motion, your sample could be reduced to :

constructor() {
this.euler = new THREE.Euler(0, 0, 0, 'YXZ');
this.rotationSpeed = Math.PI / 180;
}

onMouseMove(e) {
const movementX = e.movementX || e.mozMovementX || e.webkitMovementX || 0;
const movementY = e.movementY || e.mozMovementY || e.webkitMovementY || 0;

this.euler.y -= movementX * this.rotationSpeed;
this.euler.x -= movementY * this.rotationSpeed;
this.euler.x = Math.min(Math.max(this.euler.x, -1.0472), 1.0472);

this.camera.quaternion.setFromEuler(this.euler);
}