I have a camera facing the ground and I want to pan up to look at a target object in the distance.
Currently, I achieve this with the following:
Vector3 dir = targetPoint - transform.position;
Quaternion lookRotation = Quaternion.LookRotation(dir);
Quaternion newRotation = Quaternion.RotateTowards(transform.rotation, lookRotation, rotationDamping * Time.deltaTime);
transform.rotation = newRotation;
The camera performs the rotation and ends up pointing at the target object correctly, but as the camera pans up it tilts to one side making my game world set at an angle to the viewer, which is pretty disorienting:
How can I constrain the camera angle some way so that the horizon is always flat to the camera?
Thanks!
Update
Adding the line suggested by @Isaac below produces the correct rotation in relation to the horizon, but it snaps abruptly to z=0 at the start which is still not what I'm looking for.
transform.localEulerAngles = new Vector3 (transform.localEulerAngles.x, transform.localEulerAngles.y, 0);
There is an excellent Q/A on gamedev.stackexchange on this subject. You should try the pitch/yaw system suggested there.
Another suggestion is to correct for the roll of your camera during the rotation.
public float rollCorrectionSpeed;
public void Update()
{
float roll = Vector3.Dot(transform.right, Vector3.up);
transform.Rotate(0, 0, -roll * rollCorrectionSpeed);
Vector3 dir = targetPoint.position - transform.position;
Quaternion lookRotation = Quaternion.LookRotation(dir);
Quaternion newRotation = Quaternion.RotateTowards(transform.rotation, lookRotation, rotationDamping * Time.deltaTime);
transform.rotation = newRotation;
}
Edit:
There is an easier solution: Just keep the z
rotation of the Quaternion you are rotating from to 0.
public void Update()
{
Vector3 angles = transform.rotation.eulerAngles;
Quaternion from = Quaternion.Euler(angles.x, angles.y, 0);
Vector3 dir = targetPoint.position - transform.position;
Quaternion to = Quaternion.LookRotation(dir);
transform.rotation = Quaternion.RotateTowards(from, to, rotationDamping * Time.deltaTime);
}