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

Bug why localEulerAngles not returns accurate degree on x axis ?

Discussion in 'Scripting' started by Deleted User, Feb 28, 2021.

  1. Deleted User

    Deleted User

    Guest

    i tried using
    Code (CSharp):
    1.    transform.localEulerAngles.x  
    to get rotation on x axis
    it works fine as you just you can see in this picture





    as fine as rotating it manually from 360 to 270



    as not fine as i tried to keep rotating it manually
    as you see instead of printing 250 it is printing 290
     
  2. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,446
    That's because Unity does not work with euler angles internally. Eulerangles build up a specific gimbal hierarchy. You can or should never look at single angles as euler angles represent a system of 3 gimbals and 3 angles to represent the rotation / orientation in space. Specifically Unity uses -180° to180° on the y and z axis and -90 to 90 on the x axis. The classical camera mount. When you read the localEulerAngles Unity converts the quaternion (which does not suffer from gimbal lock since it does not have any gimbals) into euler angles. Note that the same rotation can be achieved with different combinations of euler angles. X in our case is the middle axis and that's always the one that suffers from gimbal lock. So when you rotate over the apex your X rotation essentally represents the elevation on the "other side". What's the exact result is hard to tell because it depends on the exact conversion routine Unity uses. Anyways you can only look at euler angles as a whole system, not at single values.

    Note that the euler angles you set in the inspector are stored seperately in the editor only to make editing easier. Here you can rotate way beyond 0 to 360 or -180 to 180 degree for convenience. However when converting back from the quaternion representation the angles will be limited to those ranges.

    3D rotations are quite complex and quaternions are an elegant and simple solution to this problem. However they are not as intuitive as euler angles are.
     
    Deleted User likes this.
  3. Deleted User

    Deleted User

    Guest

    yeah really complex .totally it is , if you have a way to solve this problem with quaternions . can you provide me with it .
    because i am not well-familiar with quaternions .
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,336
    What is the problem you're trying to solve? You can always just rotate things using .Rotate() and providing a rotation about any arbitrary axis (a Vector3), perhaps generated with Quaternion.AngleAxis()
     
  5. Deleted User

    Deleted User

    Guest

    when i try to clamp the rotation of my car for between the range [ 45 , 325 ] .
    "btw i am using my CustomClamp() method to make the clamped rotation smoothly "

    the clamping is really working fine
    and this is how the mechanic of my func :
    if the car skipped the 45 deg , and it is at 55 ,
    i get the rotation through :



    float xRot = transform.localEulerAngles.x ;

    transform.rotation = Quternion.Euler( --xRot , 0 , 0 );


    the code is litlle bit tall but this is the basic idea .
    and that happens because when you are setting values,
    to a rotation this is how unity will manipulate and read those values :





    but once the car rotated over the 90 . that would causes a problem of direction .
    so as i saw the clamped area became reversed .
    so this is how the direction is becoming :



    so this is my main issue .

    and I assume this happens because when you are getting values from eulerAngles of X axis
    is not similar while setting the rotation using Euler . as just the first answer mentiond .

    while you are getting values of X rot.
    this is how it is manipulated as i put in my post :

     
  6. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,336
    As bunny points out above, those angles are mostly just for show in the editor.

    To do what you're contemplating, one approach is to track your own local
    float angle;
    variable, adjust and clamp it, then apply it to one of your transforms to get the drift angle you want. Here's a discussion around this concept but with a different focus, getting a gun turret to travel smoothly and elevate smoothly.

    Turret aiming/rotating:

    https://forum.unity.com/threads/vector-lookat-unprecise.858511/#post-5658304
     
    Deleted User likes this.
  7. Deleted User

    Deleted User

    Guest

    so instead of diving into mathematic calculations . i used another approach .
    i added these lines intop of my CustomClamp method .
    so these lines of code that i created will check the direction if its back then will moveItBack
    Code (CSharp):
    1.      
    2.        float turnBackSpeed = 10;
    3.  
    4.         float forwardDirection = Mathf.Sign(transform.forward.z);
    5.  
    6.         if (forwardDirection == -1)
    7.         {
    8.             float xRot = transform.localEulerAngles.x;
    9.             bool isItDownBack = Enumerable.Range(0, 90).Contains((int) xRot);
    10.  
    11.             if (isItDownBack)
    12.             {
    13.                         transform.localEulerAngles =
    14.                                       transform.localEulerAngles
    15.                                       + Vector3.left * Time.deltaTime * turnBackSpeed
    16.                                                      * forwardDirection;
    17.             }
    18.             else
    19.             {
    20.                 transform.localEulerAngles =
    21.                     transform.localEulerAngles
    22.                     - Vector3.left * Time.deltaTime * turnBackSpeed
    23.                                    * forwardDirection;
    24.             }
    25.          
    26.             return;
    27.         }
    28.  
     
  8. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,735
    That is quite an extreme workaround. It's not only relatively computationally expensive for what it does(you iterate through all numbers 0 through 90 instead of just checking if x >= 0f && x < 90f??), I'd also be surprised if it actually works in all cases. There are tons of combinations of Euler numbers that are a valid interpretation of a given rotation; you've got this working for one or two of them, but there can easily be more that your code won't account for.

    It's also odd to me that you did this workaround " instead of diving into mathematic calculations" but it has FAR MORE calculations in it than Kurt's suggestion above.

    A general piece of advice when dealing with rotations would be, never read out transform.eulerAngles (et al); treat it as assignment only. There are a number of tricks you can use in situations where you would be tempted to read out eulerAngles that I've written out in this article - give that a read.

    The best answer for you is going to be @Kurt-Dekker 's solution, of tracking your rotation in your own variable, clamp that, and assign that to your rotation.

    Another approach would be to use Mathf.Atan2 to find the angle you're currently at. This can get you a similar result to what you're trying to get out of eulerAngles.x, but crucially, it is not affected by the Y and Z components of the Euler angles. You feed it the exact coordinates you want it to use and no more.
     
    bobisgod234, Kurt-Dekker and Bunny83 like this.