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);      
    }
}

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 );
		}
	}
}