2

My code is not working, I am trying to clamp the camera, but it's not working. It's snapping to 45 instantly. How can I clamp the camera?

Here is my Code.

using UnityEngine;
using System.Collections;

 public class MoveCamera : MonoBehaviour 
 {

     public float sensitivity = 4.0f;        
     private Vector3 mouseOrigin;
     private bool isRotating;

     private float minX = -45.0f;
     private float maxX = 45.0f;

     private float minY = -10.0f;
     private float maxY = 10.0f;

     float rotationY = 0.0f;
     float rotationX = 0.0f;

     void Start()
     {

     }

     void Update () 
     {

         if (Input.GetMouseButtonDown (0)) {

             mouseOrigin = Input.mousePosition;
             isRotating = true;
         }

         if (!Input.GetMouseButton (0))
             isRotating = false;

         if (isRotating) {

             Vector3 pos = Camera.main.ScreenToViewportPoint (Input.mousePosition - mouseOrigin);
             transform.RotateAround (transform.position, transform.right, -pos.y * sensitivity);
             transform.RotateAround (transform.position, Vector3.up, pos.x * sensitivity);

             rotationY = Mathf.Clamp (transform.localEulerAngles.y, minY, maxY);
             rotationX = Mathf.Clamp (transform.localEulerAngles.x, minX, maxX);
             transform.localEulerAngles = new Vector3 (-rotationY, rotationX, 0);
         }
     }
 }
Daniel
  • 2,355
  • 9
  • 23
  • 30
Jamshaid Alam
  • 515
  • 1
  • 9
  • 24
  • transform.RotateAround actually rotates the transform, so every update you're rotating, then rotating again with transform.localEulerAngles. What are you wanting the camera to do? – Absinthe Oct 04 '16 at 18:34
  • i want the camera to clamp Y axis to 10 and -10, and X axis to 45 and -45 – Jamshaid Alam Oct 04 '16 at 18:38
  • if i remove last 3 line, its rotating perfectly as i wanted. but i want to clamp so i added last 3 line but its not clamping. – Jamshaid Alam Oct 04 '16 at 18:40
  • Ok, so rather than use transform.RotateAround calculate your angles first, clamp them, then use transform.rotation = whatever. There are various methods you can use in the Quaternion and Vector3 classes to help you with the angles – Absinthe Oct 04 '16 at 18:53
  • Actually, i m new to this, Can you correct the code and post as an answer? I will accept the answer. By the way thanks for quick reply :) @Absinthe – Jamshaid Alam Oct 04 '16 at 18:58
  • Try transform.Rotation = Quaternion.LookRotation(pos) after your 'Vector3 pos =' line. Delete everything after. Does that work? Happy to code an answer for you if not when I have time. – Absinthe Oct 04 '16 at 20:42
  • @Absinthe No its not working :( – Jamshaid Alam Oct 05 '16 at 04:28

2 Answers2

0

Here's an example of limiting the Y axis rotation, you can adapt it for X too. You didn't state what the limit should be based on so here it's based on the rotation of another object (public Transform target), this could be your player or whatever.

public float sensitivity = 16.0f;
public Transform target;

void Update()
{

    if (Input.GetMouseButton(0))
    {
        //Debug.Log(Quaternion.Angle(transform.rotation, target.rotation));
        float angle = Quaternion.Angle(transform.rotation, target.rotation);
        if(angle < 45 || angle > 315)
        {
            Vector3 pos = Camera.main.ScreenToViewportPoint(Input.mousePosition);
            transform.RotateAround(pos, Vector3.up, Time.deltaTime * sensitivity);
        }

    }
}

If instead you want to limit based on world space just check the rotation of the camera:

public float sensitivity = 16.0f;
//public Transform target;

void Update()
{

    if (Input.GetMouseButton(0))
    {

        float angle = transform.eulerAngles.y;
        Debug.Log(angle);
        if (angle < 45 || angle > 315)
        {
            Vector3 pos = Camera.main.ScreenToViewportPoint(Input.mousePosition);
            transform.RotateAround(pos, Vector3.up, Time.deltaTime * sensitivity);
        }

    }
}

Note in both cases the use of Time.deltaTime to ensure the rotation appears to happen at the same speed regardless of the players frame-rate.

If you want to reverse the rotation invert the axis argument of RotateAround:

transform.RotateAround(pos, -Vector3.up, Time.deltaTime * sensitivity);
Absinthe
  • 3,258
  • 6
  • 31
  • 70
0

I fixed it. Here is Complete code.

using UnityEngine;
using System.Collections;

public class MoveCamera : MonoBehaviour 
{

    public float sensitivity = 4.0f;        
    private Vector3 mouseOrigin;
    private bool isRotating;
    public GameObject cam;

    void Start()
    {
    }

    protected float ClampAngle(float angle, float min, float max) {

        angle = NormalizeAngle(angle);
        if (angle > 180) {
            angle -= 360;
        } else if (angle < -180) {
            angle += 360;
        }

        min = NormalizeAngle(min);
        if (min > 180) {
            min -= 360;
        } else if (min < -180) {
            min += 360;
        }

        max = NormalizeAngle(max);
        if (max > 180) {
            max -= 360;
        } else if (max < -180) {
            max += 360;
        }

        return Mathf.Clamp(angle, min, max);
    }

    protected float NormalizeAngle(float angle) {
        while (angle > 360)
            angle -= 360;
        while (angle < 0)
            angle += 360;
        return angle;
    }


    void Update () 
    {

        if (Input.GetMouseButtonDown (0)) {

            mouseOrigin = Input.mousePosition;
            isRotating = true;
        }

        if (!Input.GetMouseButton (0))
            isRotating = false;

        if (isRotating) {

            cam.transform.localEulerAngles = new Vector3(0, ClampAngle(cam.transform.localEulerAngles.y, -45, 45), 0);
            Vector3 pos = Camera.main.ScreenToViewportPoint (Input.mousePosition - mouseOrigin);
            transform.RotateAround (transform.position, transform.right, -pos.y * sensitivity);
            transform.RotateAround (transform.position, Vector3.up, pos.x * sensitivity);
        }
    }
}
Jamshaid Alam
  • 515
  • 1
  • 9
  • 24