Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Rotating on X Y Axis only.

Discussion in 'Scripting' started by Garrus7, Aug 5, 2012.

  1. Garrus7

    Garrus7

    Joined:
    Aug 5, 2012
    Posts:
    12
    I'm trying to write a script to rotate the camera using the mouse, but I can't stop it from tilting on the Z axis.

    Code (csharp):
    1. float axisX = Input.GetAxisRaw("Mouse X");
    2. float axisY = Input.GetAxisRaw("Mouse Y");
    3. gameObject.transform.Rotate(new Vector3(-axisY, axisX, 0), Space.World);
    Using this code if I move the mouse in an XY axis (towards the corners of the screen) the camera starts tilting on the Z axis.

    What am I doing wrong?
     
  2. RoDester

    RoDester

    Joined:
    May 21, 2011
    Posts:
    64
    Try adding this.

    Code (csharp):
    1.  
    2.  
    3. function LateUpdate(){
    4. gameObject.transform.rotation.z = 0;
    5. }
    6.  
    7.  
     
  3. Garrus7

    Garrus7

    Joined:
    Aug 5, 2012
    Posts:
    12
    I tried this:

    Code (csharp):
    1.     void LateUpdate() {
    2.         Quaternion zlock = this.transform.rotation;
    3.         zlock.z = 0;
    4.         gameObject.transform.rotation = zlock;
    5.     }
    and I still get rotation on Z. even though debug.log(gameobject.transform.rotation); shows a 0 on the z axis, when I look at the transform on the editor I can see the Z value changing, and it's never 0.
     
  4. jessica1986

    jessica1986

    Joined:
    Feb 7, 2012
    Posts:
    621
    local or global issue ?
     
  5. Garrus7

    Garrus7

    Joined:
    Aug 5, 2012
    Posts:
    12
    Not sure, I've tried

    Code (csharp):
    1. gameObject.transform.Rotate(new Vector3(-axisY, axisX, 0), Space.Self);
    2. gameObject.transform.Rotate(new Vector3(-axisY, axisX, 0), Space.World);
    3.  
    4. gameObject.transform.RotateAround(Vector3.up, axisX * Time.deltaTime);
    5. gameObject.transform.RotateAround(Vector3.right, -axisY * Time.deltaTime);
    6.  
    7. gameObject.transform.RotateAroundLocal(Vector3.up, axisX * Time.deltaTime);
    8. gameObject.transform.RotateAroundLocal(Vector3.right, -axisY * Time.deltaTime);
    and still get the same problem.
     
  6. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,400
    transform.rotation is a 4D quaternion, and rotation.z does not correspond to the z axis nor is it in degrees.

    To see what's happening, click on an object in the editor, then use the rotate tool to rotate it on the x axis by say 45 degrees, then rotate it on the y axis by 45 degrees, and watch what happens to the rotation in the inspector. Instead, you could basically do what the standard first person controller/MouseLook script does, namely have an empty object for y axis rotation and the camera as a child of that object for x axis rotation. By the way you can just write "transform.Rotate", you don't need "gameObject.transform.Rotate".

    --Eric
     
    stratos_kakalis likes this.
  7. Garrus7

    Garrus7

    Joined:
    Aug 5, 2012
    Posts:
    12
    Thanks, that worked.
     
  8. elfjman

    elfjman

    Joined:
    Aug 8, 2015
    Posts:
    2
    It solves.
    But, can someone please explain what is going on there. Is that the "Gimbal Lock" problem using Euler angles?
     
  9. stratos_kakalis

    stratos_kakalis

    Joined:
    Mar 8, 2016
    Posts:
    4
    I can understand why it works even thought im still trying to understand why a lateUpdate function wouldnt work.Thanks it was bugging me but i used your tips and it worked
     
  10. parixit2411

    parixit2411

    Joined:
    Nov 10, 2021
    Posts:
    12
    We can also use different spaces for each rotation.

    Code (CSharp):
    1. transform.Rotate(Vector3.up, axisX, Space.World);
    2. transform.Rotate(Vector3.right, axisY, Space.Self);
    You can do this with a single object.

    Edit: Y rotation has to be in world space.

    Code (CSharp):
    1. transform.Rotate(Vector3.up, axisX, Space.Self);
    2. transform.Rotate(Vector3.right, axisY, Space.World);
    This will not work.
     
  11. BenevolenceGames

    BenevolenceGames

    Joined:
    Feb 17, 2021
    Posts:
    128
    It doesn’t work because a rotation in Unity is naturally expressed as a 4 dimensional construct known as the Quaternion. Here’s some educational stuff —

    https://quaternions.onlin/
    https://eater.net/quaternions


    You are used to the three dimensional representation of a rotation shown within the editor which is expressed in Euler angles. In code, to AVOID gimbal locking, we rotate things with quaternion. You can use transform.rotation.eulerAngles but I do believe that’s a get only property. I think all assignments have to be done in quaternion.


    Also, there’s this

    https://docs.unity3d.com/ScriptReference/Quaternion-operator_multiply.html
     
    Last edited: Feb 12, 2023
  12. LethalGenes

    LethalGenes

    Joined:
    Jan 31, 2023
    Posts:
    69
    Id hate to be the thread police here, but this was from 2016, and prior to that 2012 !

    Using the correct technique gimbal locking should be non-existent. The rasteriser that unity engine was built with the guidance of had not implemented quaternion. The mythos of quaternion being fundamental to the engine is specific to the auto-wrap values of its struct and nothing more. Operating on an Euler angle is different to operating on a vector 3, however a vector 3 can be converted to Euler angles without any unwanted operation.
     
  13. BenevolenceGames

    BenevolenceGames

    Joined:
    Feb 17, 2021
    Posts:
    128
    Sheesh! I really need to pay more attention to dates on the OP. Good call, sorry about the necro.