Search Unity

  1. Get all the Unite Berlin 2018 news on the blog.
    Dismiss Notice
  2. Unity 2018.2 has arrived! Read about it here.
    Dismiss Notice
  3. We're looking for your feedback on the platforms you use and how you use them. Let us know!
    Dismiss Notice
  4. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  5. Improve your Unity skills with a certified instructor in a private, interactive classroom. Learn more.
    Dismiss Notice
  6. ARCore is out of developer preview! Read about it here.
    Dismiss Notice
  7. Magic Leap’s Lumin SDK Technical Preview for Unity lets you get started creating content for Magic Leap One™. Find more information on our blog!
    Dismiss Notice
  8. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

Why is my camera rotation clamp not working?

Discussion in 'Scripting' started by TheGoopyPixel, Aug 12, 2018 at 11:57 PM.

  1. TheGoopyPixel

    TheGoopyPixel

    Joined:
    Apr 29, 2017
    Posts:
    111
    I'm just trying to make a script that locks the players X rotation between 60 and -60. Looking down at X 60 works just fine, but when I looks up at X -60 the camera goes berserk for seemingly no reason. Please help!

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class PlayerLook : MonoBehaviour
    6. {
    7.     public Transform playerBody;
    8.     public float mouseSensitivity;
    9.  
    10.     float xAxisClamp = 0.0f;
    11.  
    12.     void Awake()
    13.     {
    14.         Cursor.lockState = CursorLockMode.Locked;
    15.     }
    16.  
    17.     void Update()
    18.     {
    19.         RotateCamera();
    20.     }
    21.  
    22.     void RotateCamera()
    23.     {
    24.         float mouseX = Input.GetAxis("Mouse X");
    25.         float mouseY = Input.GetAxis("Mouse Y");
    26.  
    27.         float rotAmountX = mouseX * mouseSensitivity;
    28.         float rotAmountY = mouseY * mouseSensitivity;
    29.  
    30.         xAxisClamp -= rotAmountY;
    31.  
    32.         Vector3 targetRotCam = transform.rotation.eulerAngles;
    33.         Vector3 targetRotBody = playerBody.rotation.eulerAngles;
    34.  
    35.         targetRotCam.x -= rotAmountY;
    36.         targetRotCam.z = 0;
    37.  
    38.         targetRotBody.y += rotAmountX;
    39.  
    40.         if(xAxisClamp > 60)
    41.         {
    42.             xAxisClamp = 60;
    43.             targetRotCam.x = 60;
    44.         }
    45.         else if(xAxisClamp < -60)
    46.         {
    47.             xAxisClamp = -60;
    48.             targetRotCam.x = 240;
    49.         }
    50.  
    51.         transform.rotation = Quaternion.Euler(targetRotCam);
    52.         playerBody.rotation = Quaternion.Euler(targetRotBody);
    53.     }
    54. }
    55.  
     
  2. fire7side

    fire7side

    Joined:
    Oct 15, 2012
    Posts:
    1,700
    You are getting EulerAngles from the rotation, which gives a different result in my experience. I've seen the description about it in the manual.
    Try this, from my experiments it gives a different result instead of:
    Code (csharp):
    1.  
    2. Vector3 targetRotCam = transform.rotation.eulerAngles;
    3.  
    Try:
    Code (csharp):
    1.  
    2. Vector3 targetRotCam = transform.eulerAngles;
    3.  
    I don't know if it will work in your case, I just know I was copying rotation to another object and it kept reversing until I used eulerAngles from the transform. If it's not working the way you want, have it print the angles in debug and you'll figure it out.
    The reason given in the manual is that a eulerAngle from a quaternion only goes up to 180 degrees instead of 360. In my case, when I was copying a revolving object, it would copy half way and then reverse direction from rotation, but would do an exact copy when getting eulerAngles directly from the transform.
     
    Last edited: Aug 13, 2018 at 12:29 AM
  3. TheGoopyPixel

    TheGoopyPixel

    Joined:
    Apr 29, 2017
    Posts:
    111
    This did not work
     
  4. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    1,571
    If you're driving both values manually yourself (as in other forces aren't in play), it's much easier to store the values separately as pitch and yaw, clamp them and rebuild the rotation every frame.

    Code (csharp):
    1.  
    2. float pitch, yaw; // up in the class
    3.  
    4. void Update()
    5. {
    6.    pitch = Mathf.Clamp(pitch + Input.GetAxis("Mouse Y"), -60, 60);
    7.    yaw += Input.GetAxis("Mouse X");
    8.  
    9.    transform.rotation = Quaterion.Euler(pitch, yaw, 0f);
    10. }
    11.  
    No rollover, no math to unfold your Quaternions properly, etc.

    I just typed this here but you get the idea.
     
    Last edited: Aug 13, 2018 at 1:25 AM
  5. TheGoopyPixel

    TheGoopyPixel

    Joined:
    Apr 29, 2017
    Posts:
    111
    Alright this did succesfully clamp the camera's X rotation (up/down) to between -60 and 60. But now i'm having another problem. Basically the camera look script also controls the player body gameobject, so the player spins around with the camera (which is what literally every first person game does). But with this updated script you've provided me it's producing spastic Y rotation (left/right) movement and I'm not sure why; it jumps around slightly as I spin around. The camera is a child of the player gameobject by the way.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class PlayerLook : MonoBehaviour
    6. {
    7.     public Transform playerBody;
    8.     public float mouseSensitivity;
    9.  
    10.     float pitch;
    11.     float yaw;
    12.  
    13.     void Awake()
    14.     {
    15.         Cursor.lockState = CursorLockMode.Locked;
    16.     }
    17.  
    18.     void Update()
    19.     {
    20.         RotateCamera();
    21.     }
    22.  
    23.     void RotateCamera()
    24.     {
    25.         float mouseX = Input.GetAxis("Mouse X");
    26.         float mouseY = Input.GetAxis("Mouse Y");
    27.         float rotAmountX = mouseX * mouseSensitivity;
    28.         float rotAmountY = mouseY * mouseSensitivity;
    29.         Vector3 targetYawBody = playerBody.eulerAngles;
    30.         targetYawBody.y += rotAmountX;
    31.  
    32.         pitch = Mathf.Clamp(pitch - rotAmountY, -60f, 60f);
    33.         yaw += rotAmountX;
    34.  
    35.         transform.rotation = Quaternion.Euler(pitch, yaw, 0f);
    36.         playerBody.rotation = Quaternion.Euler(targetYawBody);
    37.     }
    38. }