My goal is to program a camera to point towards the mouse cursor. I attached the following script to the Main Camera.
using UnityEngine;
using System.Collections;
public class CameraController : MonoBehaviour {
public float sensitivity;
// Update is called once per frame
void Update () {
transform.Rotate (Input.GetAxis ("Mouse Y") * -1 * sensitivity, Input.GetAxis ("Mouse X") * sensitivity, 0);
}
}
I "told" the camera to rotate around the x and y axes. Whenever it does this, the camera tilts sideways. When I checked the rotation of Main Camera, I saw that the z rotation had changed. Why is it rotating around the z axis when I left it at 0?
Answer
Rotations are extremely order-dependent. Doubly so when you're composing rotations in local space (so the axes you're rotating around are themselves rotating from one frame to the next)
As an extreme example, imagine that you start facing z+, and in one frame you pitch (x rotation) 90 degrees up.
In the next frame, you yaw (y rotation) 90 degrees left. Since you're already looking straight up, your local y axis is pointing "back" along the world z- axis, so this leaves you looking along the x- axis, with your local y axis still pointing "back" along world z-.
This is the same as yawing 90 degrees left and then rolling (z rotation) 90 degrees left.
So: composing local x & y rotations, compounded from frame to frame, can turn into z rotations.
One way to fix this is to always pitch along your local x axis, but always yaw around the world y axis (if you always want the camera "up" vector facing up). eg:
void Update () {
float pitch = Input.GetAxis ("Mouse Y") * -1f * sensitivity;
transform.Rotate (pitch * Vector3.right, Space.Self);
float yaw = Input.GetAxis ("Mouse X") * sensitivity;
transform.Rotate (yaw * Vector3.up, Space.World);
}
Note that this still has the problem of gimbal lock common to Euler angle / yaw-pitch-roll rotation systems, and isn't suitable if you want the player to be able to point their camera straight up or straight down.
No comments:
Post a Comment