Search Unity

Why is my camera rotation clamp not working?

Discussion in 'Scripting' started by VileGoo, Aug 12, 2018.

  1. VileGoo

    VileGoo

    Joined:
    Apr 29, 2017
    Posts:
    220
    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,819
    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
  3. VileGoo

    VileGoo

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

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    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
    skiffman7080 likes this.
  5. VileGoo

    VileGoo

    Joined:
    Apr 29, 2017
    Posts:
    220
    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. }
     
  6. YJPLAPIAN

    YJPLAPIAN

    Joined:
    Sep 13, 2018
    Posts:
    1
    @VileGoo, I'm not a hundred percent sure on this one since I am a beginner to this all. But make an open variable public Camera cam and rewrite it so that the input rotation affects the camera instead of the whole body.
     
    Last edited: Nov 5, 2019