Search Unity

Bug transform.localEulerAngles resulting in incorrect values

Discussion in 'Editor & General Support' started by CoolJosh3k, Jan 12, 2021.

  1. CoolJosh3k

    CoolJosh3k

    Joined:
    Dec 3, 2016
    Posts:
    145
    I notice that if I try to set the localEulerAngles to something like (0, 0, 90) for example, it is possible to end up with any value that where (value %= 360) == 90.

    For example, if I set localEulerAngles.z in the inspector to something like -1000 and run code to set it to 90f, it ends up showing -990 while localEulerAngles.z returns the correct value of 90f.

    Is this intended behaviour? Is there something else I should write in my code to fix this display issue?

    Here is an quick example of where I encouter the problem:

    Code (CSharp):
    1. public class ExampleClass : MonoBehaviour
    2. {
    3.     void OnDrawGizmosSelected() {
    4.         if (EditorGUI.actionKey) {
    5.             var e = transform.localEulerAngles;
    6.             e.z = RoundToNearest(e.z, 90f);
    7.             e.z %= 360f;
    8.             transform.localEulerAngles = e;
    9.         }
    10.     }
    11. }
    Should I perhaps go ahead and file a bug report?
     
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,909
    This is not a bug.

    Unity stores rotations as Quaternions. Euler angles are merely a convenient representation for the UI.

    When you write to localEulerAngles, Unity converts the value you give to a quaternion before applying it to the transform. Later, to display the value in the inspector, the quaternion is comverted back into euler angles.

    This conversion is not unique There are infinitely many sets of Euler angles that can represent the same quaternion. So sometimes the one you get back out is not the one you put in.
     
    Joe-Censored likes this.
  3. CoolJosh3k

    CoolJosh3k

    Joined:
    Dec 3, 2016
    Posts:
    145
    I would typically expect converting from a quaternion to the euler angles to use the values 0 to 360. For some reason Unity is holding onto a prefered result, based on what the previous euler angles were.

    How can I tell Unity to generate the euler angles, but without any prior notion as to what the preferred set would be?
     
  4. Madgvox

    Madgvox

    Joined:
    Apr 13, 2014
    Posts:
    1,317
    Out of curiousity, what is the reason you care about what values are displayed in the editor?
     
  5. CoolJosh3k

    CoolJosh3k

    Joined:
    Dec 3, 2016
    Posts:
    145
    There are plenty of annoying little things (and some major) in Unity.

    A simply display issue like this is confusing. I'll just have to remember that if I either:
    want to get back exactly what is shown in the editor I cannot just do transform.rotation.eulerAngles
    or store a value outside of the usual set of 0 to <360,
    as I cannot rely on the inspector.

    While I currently am a solo developer, I can see where this could be super confusing for team members less experienced with Unity and its quirks.

    I believe that the inspector should either show exactly what the value would be if used, or remember which set of numbers is used when read/written.
     
  6. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    My guess is because even though the euler angles you enter into the inspector are only used by the transform after conversion to a quaternion, they are actually serialized as euler angles the way you typed them for inspector purposes. Unity probably bases future inspector representations of the angle on previous values entered, to avoid certain visual annoyances. Maybe otherwise you'd see things like angles continually flipping between 180 and -180, 270 and -90, etc. Might get irritating. Just a guess.

    As far as displaying the angle without any bias from what is entered into the inspector, just create a script which outputs localEulerAngles to the inspector panel every frame. My guess is you'll see the output as even more nonsensical than the current behavior you are seeing. But it might actually help with what you're trying to do.
     
  7. Madgvox

    Madgvox

    Joined:
    Apr 13, 2014
    Posts:
    1,317
    Some insight into why it behaves this way: There is an extra hidden property of Transform called
    m_LocalEulerAnglesHint
    . It's set when you input a value manually into the Transform inspector, to hide the ugly Quaternion and give you clean values when working with Euler angles in the inspector. This value gets reset to the converted value if the rotation is set in any way other than through the inspector.

    The behavior outlined in the OP is almost certainly an artifact of this conversion process. Since you're initially retrieving the converted value (not the clean Euler angle from the inspector), your x and y will most likely have "strange" values. This will persist through the set, and probably color the way it gets converted in the future (even though the ending rotation is the same).

    In my workflow, I have developed a policy of not paying attention to the Euler angles displayed in the inspector, and more generally speaking to converted Euler angle values at all. Instead, I work with visualizations of rotations via Debug.DrawRay or gizmos, which give me a much more intuitive understanding of the behavior of the underlying Quaternion.
     
    Last edited: Jan 13, 2021
  8. CoolJosh3k

    CoolJosh3k

    Joined:
    Dec 3, 2016
    Posts:
    145
    Thanks. I will check out that hidden property.