Search Unity

Bug X axis rotation error using transform.eulerAngles

Discussion in 'Editor & General Support' started by ttesjt, Oct 27, 2022.

  1. ttesjt

    ttesjt

    Joined:
    Jun 25, 2020
    Posts:
    13
    Hi all.

    I am using editor version 2021.3.7f1

    The behavior is when I rotate an object along x axis using eulerAngles/localEulerAngles in Update(), and the x angle's value is greater than 90 or smaller than -90, the x angle's value will be jumping between 90/-90 +- the current value to 90/-90.

    For example, if my value is set to 92. The object's x angle will be jumping between 92 and 88. Here is another video shows the behavior:


    By the way. Rotation using the same method has been working fine on both y and z axis. Just x axis is having the trouble.

    I have attached the demo script.


    I don't know if this was fixed already. I don't think this is intended anyway, so if this is already fixed in a later version, I will make an update.

    Thank you all!
     

    Attached Files:

    afshin_a_1 likes this.
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,742
  3. ttesjt

    ttesjt

    Joined:
    Jun 25, 2020
    Posts:
    13

    Thank you for the reply. I can not read the link you sent to me because of authorization problem. But If you would, could you answer two very quick questions.

    1: Can you confirm that what is showing in the video is normal.

    2: Why different axis acting differently to numbers? (The same code work fine rotating y and z axis, but not the x)


    I would be very shocked to know the limitation of euler with x axis because it's very basic things and I never even heard of it since learning matrix back in college. I know ways to rotate, but I just don't understand why using euler angles having problem specifically with x axis. Thank you so much if you would add things to my knowledge base.
     
  4. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,927
    1: Kinda sorta yes. It's going to be down to your code of course.
    2: Because the values you see in the inspector are just 'nice looking' representation of what actually goes on under the hood with Unity and rotations.

    Unity uses Quaternions for rotations (super complicated mathematical thing), while the Inspector shows the XYZ euler angles of this rotation. Though these numbers aren't the 'real' rotation either. If you where to Debug.Log the
    transform.rotation.eulerAngles
    you'll find they don't match what the inspector shows.

    Euler angles can represent multiple different kinds of rotations too, so you hit situations like the one you're experiencing.

    If you want to rotate something around an axis, you probably want to use Quaternion.AngleAxis or similar. Nonetheless, using euler angles to manage rotation always leads to headache.
     
    Last edited: Oct 28, 2022
    Kurt-Dekker likes this.
  5. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,927
    For completeness sake here's a simple script that will rotation a game object around an axis by x degrees per second:

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class AxisRotator : MonoBehaviour
    4. {
    5.     [SerializeField]
    6.     private TransformAxis rotationAxis = TransformAxis.X;
    7.     [SerializeField]
    8.     private float rotationSpeed;
    9.     private void Update()
    10.     {
    11.         Vector3 axis = Vector3.up;
    12.    
    13.         switch (rotationAxis)
    14.         {
    15.             case TransformAxis.X:
    16.                 axis = transform.right;
    17.                 break;
    18.        
    19.             case TransformAxis.Y:
    20.                 axis = transform.up;
    21.                 break;
    22.            
    23.             case TransformAxis.Z:
    24.                 axis = transform.forward;
    25.                 break;
    26.         }
    27.      
    28.        Quaternion rotation = Quaternion.AngleAxis(rotationSpeed * Time.deltaTime, rotationAxis);
    29.        transform.rotation = rotation * transform.rotation;
    30.     }
    31.     public enum TransformAxis
    32.     {
    33.         X,
    34.         Y,
    35.         Z
    36.     }
    37. }
    Written in notepad++ so maybe some errors.

    Also OP you need to space your code our properly. This is unreadable:
    Code (CSharp):
    1.         if (axis == "x") {
    2.             angels.x = angle;
    3.         } else if (axis == "y") {
    4.             angels.y = angle;
    5.         } else if (axis == "z") {
    6.             angels.z = angle;
    7.         }
     
    Last edited: Apr 6, 2023
  6. ttesjt

    ttesjt

    Joined:
    Jun 25, 2020
    Posts:
    13

    Thank you so much for the explanation. I may be wordy, but one last thing to ask. Is it normal to have this behavor:

    "Consistently setting the x axis euler angle to the SAME value in Update() leads to this problem as well. "

    The same problem happens even there is no dynamic rotation. Like I will get the same "jumping effect" if in Update(), I keep setting the eulerAngles' x to a value for example 95.


    Thank you for correcting my codes also. This is actually a simplified version of error reproduction. You truly warmed my heart by correcting them line by line. It helps me learning a more formal way of rotation. Thanks.
     
  7. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,927
    Pretty much everything I already said answers this question.
     
    ttesjt likes this.
  8. ttesjt

    ttesjt

    Joined:
    Jun 25, 2020
    Posts:
    13
    Cool! Thank you sooo much! I will then try my best removing all the eulers in my codes. Thought they were so handy!
     
  9. afshin_a_1

    afshin_a_1

    Joined:
    Apr 26, 2015
    Posts:
    52
    me too having the same problem. only x axis using unity 2022.2.13 :/
    Code (CSharp):
    1.        
    2. void Update()
    3.     {
    4.         if (_targetAxis == TargetAxis.X)
    5.         {
    6.             transform.eulerAngles = new Vector3(transform.eulerAngles.x + 1, 0,0);
    7.         }
    8.         else if (_targetAxis == TargetAxis.Y)
    9.         {
    10.             transform.eulerAngles = new Vector3(0, transform.eulerAngles.y + 1, 0);
    11.         }
    12.         else
    13.         {
    14.             transform.eulerAngles = new Vector3(0, 0, transform.eulerAngles.z + 1);
    15.         }
    16.     }
    17.  
    all other axis works perfectly except x axis when it reaches 90
     
  10. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,927
    It's not a Unity problem as has already been explained, it's a limitation using euler angles in general.

    I already wrote a script above showing how to correctly rotate on an axis.
     
    Kurt-Dekker likes this.