- Home /
Clamp camera quaternion so you can't look up or down more than 90 degrees?
I'm trying to limit my camera movements in order to avoid it "flipping" when you look up or down further than 90 degrees, while keeping the Up vector always pointing up.
I'm currently using the following:
// Process controls
var cdir : Vector3 = transform.rotation * Vector3.forward;
cdir = (Quaternion.AngleAxis(rotX, axisX)) * cdir;
cdir = (Quaternion.AngleAxis(rotY, Vector3.Cross(cdir, Vector3.up).normalized)) * cdir;
transform.rotation = Quaternion.LookRotation(cdir);
I would like to clamp the vertical (axisY) angle to something between -89 and 89 degrees, but I fail to find a proper way to do this. I believe it shall be easier to do this in the quaternion domain, but I don't know how to test for this.
Answer by Cherno · May 17, 2014 at 10:45 PM
Take a look at this mouselook script.
public enum RotationAxes { MouseXAndY = 0, MouseX = 1, MouseY = 2 }
public RotationAxes axes = RotationAxes.MouseXAndY;
public float sensitivityX = 15F;
public float sensitivityY = 15F;
public float minimumX = -360F;
public float maximumX = 360F;
public float minimumY = -60F;
public float maximumY = 60F;
float rotationY = 0F;
void Update ()
{
/*
if (axes == RotationAxes.MouseXAndY)
{
float rotationX = transform.localEulerAngles.y + Input.GetAxis("Mouse X") * sensitivityX;
rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
rotationY = Mathf.Clamp (rotationY, minimumY, maximumY);
transform.localEulerAngles = new Vector3(-rotationY, rotationX, 0);
}
else if (axes == RotationAxes.MouseX)
{
transform.Rotate(0, Input.GetAxis("Mouse X") * sensitivityX, 0);
}
else
{
rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
rotationY = Mathf.Clamp (rotationY, minimumY, maximumY);
transform.localEulerAngles = new Vector3(-rotationY, transform.localEulerAngles.y, 0);
}
*/
if(Screen.lockCursor == true) {
if (axes == RotationAxes.MouseXAndY) {
float rotationX = new float();
if(transform.parent != null && transform.parent.CompareTag("Player") == true) {
rotationX = transform.parent.transform.localEulerAngles.y + Input.GetAxis("Mouse X") * sensitivityX;
rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
rotationY = Mathf.Clamp (rotationY, minimumY, maximumY);
transform.parent.transform.localEulerAngles = new Vector3(0, rotationX, 0);
transform.localEulerAngles = new Vector3(-rotationY, 0, 0);
}
else if(transform.parent != null) {
rotationX = transform.parent.transform.localEulerAngles.y + Input.GetAxis("Mouse X") * sensitivityX;
rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
rotationY = Mathf.Clamp (rotationY, minimumY, maximumY);
transform.parent.transform.localEulerAngles = new Vector3(0, rotationX, 0);
transform.localEulerAngles = new Vector3(-rotationY, 0, 0);
}
/*
else {
rotationX = transform.localEulerAngles.y + Input.GetAxis("Mouse X") * sensitivityX;
rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
rotationY = Mathf.Clamp (rotationY, minimumY, maximumY);
transform.localEulerAngles = new Vector3(-rotationY, rotationX, 0);
}
*/
}
else if (axes == RotationAxes.MouseX) {
if(transform.parent != null) {
transform.parent.Rotate(0, Input.GetAxis("Mouse X") * sensitivityX, 0);
}
else {
transform.Rotate(0, Input.GetAxis("Mouse X") * sensitivityX, 0);
}
}
else {
rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
rotationY = Mathf.Clamp (rotationY, minimumY, maximumY);
transform.localEulerAngles = new Vector3(-rotationY, transform.localEulerAngles.y, 0);
}
}
}
Answer by loondas · May 17, 2014 at 11:12 PM
I have been using this bit of condensed code for looking. This is also in C#
`public float updownrange = 60.0f;
float verticalrotation = 0;
public float mousesensitivity = 4.0f;
void Update ()
{
verticalrotation -= Input.GetAxis ("Mouse Y") * mousesensitivity;
verticalrotation = Mathf.Clamp (verticalrotation, -updownrange, updownrange);
Camera.main.transform.localRotation = Quaternion.Euler (verticalrotation, 0, 0)}`
This assumes the camera is a child of your character, and rotates the camera rather than your actual character. So the character collider doesn't actually move.
what if i have multiple camera and i want to be able to control it whenever i switch the camera? currently my camera2 is facing 180deg but whenever i play the game, the rotation of my camera2 will set to 0,0,0 ins$$anonymous$$d of 0,180,0. can anyone help me with this?
u need to set up two seperate $$anonymous$$ max angles under two conditions ie
public bool camera1 = false ; public bool camera2 = false ;
public camera = //find your camera ; public camera2 = //find your camera2 ;
//Starts
{
if ( camera1.enabled == true )
Camera1= true
}
{
if ( camera1.enabled == false )
Camera1= false ;
}
//ends
//Starts
{
if ( camera2.enabled == true )
Camera2= true
}
{
if ( camera2.enabled == false )
Camera2= false ;
}
//ends
//Starts
{
if (camera1 == true)
verticalrotation = $$anonymous$$athf.Clamp (verticalrotation, -updownrange, updownrange);
}
//Ends
//Starts
{
if (camera2 == true)
verticalrotation = $$anonymous$$athf.Clamp (verticalrotation, -updownrange2, updownrange2); //here you would change the clamp to suit your camera 2. ins$$anonymous$$d. by using another $$anonymous$$ max variable/float.
}
Cheers hope this helps any1.
Exvalid
//Ends
Answer by igor-pakushin · Sep 07, 2020 at 11:45 AM
using UnityEngine;
using System;
public class Orbit : MonoBehaviour
{
public Transform player;
public float turnSpeed = 4.0f;
public float offset = -13;
public Vector2 cameraRotation = new Vector2(0, 20);
void Start()
{
UpdateTransform();
}
void Update()
{
if (IsMouseDown())
{
UpdateCameraRotation();
}
UpdateTransform();
}
private void UpdateCameraRotation()
{
cameraRotation.x += Input.GetAxis("Mouse X") * turnSpeed;
cameraRotation.y -= Input.GetAxis("Mouse Y") * turnSpeed;
cameraRotation.x = Mathf.Clamp(cameraRotation.x, -180, 180);
cameraRotation.y = Mathf.Clamp(cameraRotation.y, -89, 89);
}
private void UpdateTransform()
{
var xQuaternion = Quaternion.AngleAxis(cameraRotation.x, Vector3.up);
var yQuaternion = Quaternion.AngleAxis(cameraRotation.y, Vector3.right);
var combinedQuaternion = xQuaternion * yQuaternion;
transform.position = player.position + combinedQuaternion * Vector3.forward * offset;
transform.LookAt(player.position);
}
private bool IsMouseDown()
{
return Input.GetMouseButton(0);
}
}
Put this C# script on your camera, assign player property. offset is how far an object is going to be offset from camera, cameraRotation is the angles will the camera be looking at your object