Search Unity

Question How to get the angle value on a single rotation axis without gimbal locking issues?

Discussion in 'Scripting' started by Beloudest, Dec 9, 2022.

  1. Beloudest

    Beloudest

    Joined:
    Mar 13, 2015
    Posts:
    247
    Hi, I'm struggling to get a stable value in degrees on the Z-axis from a game object rotation. This object is an oculus quest hand, I am not setting the rotation but would like to know its Z-axis rotation in degrees.

    Currently, the values from transform.eulerAngles are very unstable at various positions and suffer gimbal locking issues that make the values unusable for the purpose of normalising the value between a min and max range in degrees to control something else.

    What is the best method to deal with this scenario? How can I know the hand's rotation/angle on just a single axis from an object providing unreliable rotation values via Euler? Thanks in advance.
     
  2. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,605
    Euler Angles inherently have gimbal lock issues. Internally Unity works with Quaternions, which dont. For mapping a Quaternion to Euler Angles, there is multiple solutions, which is why these values appear unstable. The only reason the ones in the editor dont is that Unity actually has some special logic in place there, since they dont want it jumping around (people have to be able to manipulate it consistantly as well).

    For actual build applications it's usually best to work directly with quaternions in some way. Quaternions of course dont have a z axis tho - at least not one you could work with.
    I'm not entirely sure what exactly your usecase is, but maybe you can work with comparing the angles of the hand and object quaternions, or their angles compared to some axis.
    https://docs.unity3d.com/ScriptReference/Quaternion.Angle.html
    https://docs.unity3d.com/ScriptReference/Quaternion.AngleAxis.html

    Or if you need to control the other object with your hand, you could work with quaternions by actually working with directional vectors, making it look some way:
    https://docs.unity3d.com/ScriptReference/Quaternion.LookRotation.html
    (Of course you might also just directly set some objects transform.forward if that's enough)
     
    Beloudest likes this.
  3. Beloudest

    Beloudest

    Joined:
    Mar 13, 2015
    Posts:
    247
    Thanks for all the info here, it helped me get going in the right direction, pardon the pun. In the end, I solved the issue by finding the difference between a rotation from QuaternionLook each frame and then passed that difference into QuaternionAngle which gave a stable value on a single axis avoiding Euler.
     
    Yoreki likes this.