how do i Limit camera rotation on Y-Axis
Hello
I have a problems with (Mathf.Clamp) for camera Y axis. This is a simple camera controller script, everything is good the code work too, but the problem is when i try to use (Mathf.Clamp) for Y axis the camera automatic rotating !! pls what should i do ?? this is a code of script. i need another way to limit camera rotation on Y-Axis!!
 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class camera_follow : MonoBehaviour {
 
     [Header("Target")]
     public Transform    target;
     public float        distance = 3.5f;
 
     [Header("Camera speeds")]
     public float follow_speed   = 20f;
     public float y_sensitivity  = 1f;
     public float x_sensitivity  = 1f;
     
     [Header("Axis")]
     public float    y_max_axis = 2f;
     public float    y_min_axis = 0.1f;
 
     // Other private variables
     private Vector3 offset;
     private Vector3 direction;
     private float x_axis;
     private float y_axis;
 
     // Start
     void Start() {
         offset = target.position * distance;
     }
 
     // Update
     void Update() {
         // Get axis of X & Y using mouse
         x_axis = Input.GetAxis("Mouse X") * x_sensitivity;
         y_axis = Input.GetAxis("Mouse Y") * y_sensitivity;
 
         // Clamp Y axis
         // there will be no any problem if i disable this clamp
         //y_axis = Mathf.Clamp(y_axis, y_min_axis, y_max_axis);
     }
 
     // Fixed update
     void FixedUpdate() {
         // Offset
         offset = Quaternion.AngleAxis(y_axis, Vector3.right) * Quaternion.AngleAxis(x_axis, Vector3.up) * offset;
 
         // Set direction of target
         direction = target.position + offset * distance;
 
         // Trans & Look
         transform.position = Vector3.Lerp (transform.position, direction, follow_speed * Time.deltaTime);
         transform.LookAt(target.position);      
     }
 }
 
 
               you can just do
 
 if position.x> something
 position.x = something
 
                 Answer by streeetwalker · Mar 09, 2020 at 01:53 PM
HI Osama! The problem is that when you don't move the mouse y_axis is zero. But you're clamping it between your min and max,
 Therefore, when y_axis = 0, the camp returns your min value and you get constant rotation at that value. You want to limit the resulting angle based on y_axis, so clamp that, not y_axis.
 @osamaamir You're using Quaternions already, you just need to make sense of them - and I'm still learning! 
You got me going on this quest to build the perfect follower script. it is not complete yet. It doesn't do any "animation" of the camera - the camera is always the same relative distance from the player. I'm working now to limit the camera orbit angles, and also to do a spring like player-camera distance, so you get a little lag in the camera position when as move the player and the camera speed sup a little as it catches up 
Create a new project, put a cube (the "player") and a camera in the scene and place this script on the camera, and the second script on the cube. Position the camera a few meters away from the cube. Put some ground and other objects so you have a visual reference when you move around. 
 Use ASWD to move and rotate the cube. In this script you have to drag to orbit the camera. Read the code comments.
 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class CameraFollow : MonoBehaviour {
     public Transform target;
     public float distance = 3.5f; // not yet
     public float y_sensitivity = 1f;
     public float x_sensitivity = 1f;
     public float y_max_axis = 2f; // not implemented yet
     private Vector3 offset;
     private float pitch, yaw;
     private Quaternion oldRotation;
     private bool dragging = false;
 
     void Start() {
         GameObject g = gameObject;
         // to do: positon game object using distance
         transform.LookAt( g.transform ); // start out focusing on object
 
         // record these for use later
         offset = transform.position - target.position;
         oldRotation = target.transform.rotation;
         
     }
 
     // Update
     void Update() {
         // Get axis of X & Y using mouse to use when we
         // orbit the mouse around the object
         // here we are making the user left click and drag
         // if you want free movment without dragging, delete all the mousedown code
         if( Input.GetMouseButtonDown( 0 ) ) {
             dragging = true;
         }
 
         if( Input.GetMouseButtonUp( 0 ) ) {
             dragging = false;
         }
 
         if( Input.GetMouseButton( 0 ) && dragging ) {
             // to do: check if angles are between max or min, if not don't allow input
             yaw = Input.GetAxis( "Mouse X" ) * x_sensitivity;
             pitch = Input.GetAxis( "Mouse Y" ) * y_sensitivity;
         }
     }
 
     void FixedUpdate() {
         // only update if input was made
         if( Mathf.Abs(pitch - yaw) > 0.001f  ) {
             // rotate around is much easier - Quaternions do it for you
             transform.RotateAround( target.position, Vector3.up, yaw );
             transform.RotateAround( target.position, -transform.right, pitch );
             // update the offset positon if we have orbited the camera
             offset = transform.position - target.position;
         }
         // only update if we have rotated our player
         if( Quaternion.Dot( target.rotation, oldRotation ) <= 1f - 0.000001f ) {
             // get the change in rotation
             Quaternion deltaQ = target.rotation * Quaternion.Inverse( oldRotation );
             oldRotation = target.rotation;
             // apply rotation to camera offset location and rotation
             offset  =  deltaQ  * offset ;
             transform.rotation =  deltaQ * transform.rotation;
         }
         // finally, apply all the changes to the camera
         transform.position = target.position + offset;
     }
 }
 
               
 cube "player" script:
 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class MovePlayer : MonoBehaviour
 {
     public float speed = 0.05f;
 
     // Update is called once per frame
     void Update()
     {
         if( Input.GetKey( KeyCode.A ) ) {
             float angle = transform.eulerAngles.y + 1;
             transform.rotation = Quaternion.Euler( new Vector3( 0, angle, 0 ) );
         } else if( Input.GetKey( KeyCode.D ) ) {
             float angle = transform.eulerAngles.y - 1;
             transform.rotation = Quaternion.Euler( new Vector3( 0, angle, 0 ) );
         }
         if( Input.GetKey( KeyCode.W ) ) {
             transform.Translate( Vector3.forward * speed );
         } else if( Input.GetKey( KeyCode.S ) ) {
             transform.Translate( Vector3.forward * -speed );
         }
     }
 }
 
 
              @streeetwalker thank you for your comment. now i understand this :) but what can i do to limit camera rotation on Y axis. can you pleas fix this for me ?
@osamaamir , that is not simple, because you are dealing with Quaternions. It's not simple no matter what you have with angles!
I adapted this from this post, so I have not tested it. Look at the last reply here: https://forum.unity.com/threads/how-do-i-clamp-a-quaternion.370041/
This will do it, I think, so good luck! ;-)
You need a new function:
 private Quaternion ClampRotation(Quaternion q, float $$anonymous$$, float max)
 {
     q.x /= q.w;
     q.y /= q.w;
     q.z /= q.w;
     q.w = 1.0f;
  
     float angleY = 2.0f * $$anonymous$$athf.Rad2Deg * $$anonymous$$athf.Atan(q.y);
     angleY = $$anonymous$$athf.Clamp(angleY, $$anonymous$$, max);
     q.y = $$anonymous$$athf.Tan(0.5f * $$anonymous$$athf.Deg2Rad * angleY);
  
     return q;
 }
  
     // Then in your fixedupdate loop, before you calculate your 
     // offset rotation - $$anonymous$$Angle and maxAngle in degrees
     Quaternion tempRot = Quaternion.AngleAxis(y_axis, Vector3.right)
     Quaternion clampedRot = ClampRotation(tempRot, $$anonymous$$Angle, maxAngle);
       // Offset -- this replaces what you have
      offset = clampedRot * Quaternion.AngleAxis(x_axis, Vector3.up) * offset;
 
 
                  @streeetwalker if this not simple is there anther way to do this ? i mean without using transform.LookAt() ? and you know why i'm using this code because it's very smooth even when i set (targetFrameRate) to 30f.
Your answer