Search Unity

Rotations are hell (and the inspector is inconsistent with the code)

Discussion in 'Scripting' started by Aeroxima, Mar 31, 2019.

  1. Aeroxima

    Aeroxima

    Joined:
    Jul 19, 2016
    Posts:
    15
    I'm still not understanding how gimbal lock is a problem when everything is digital (and you have a baseline frame of reference in the origin's 0,0,0 rotation), why any axis needs to move to lose any degree of freedom, and they can't just all move together as a whole as they appear to (like if you rotate an apple around with lines drawn on it), but it's beyond me and I'll just accept "it is how it is".

    However, that's not what keeps causing me headaches. This is:

    There are at least 3-4 ways of representing angles in Unity.
    • Quaternion
    • Vector3 #1 (Unit vector / difference between two points)
    • Vector3 #2 #1 (Euler angles)
    • Vector3 #2 #2 (Euler angles, but where -5 is greater than 5 and it's not shown in the inspector)
    You have to print out transform.eulerAngles.x somewhere (when you would think that's what the inspector is showing already) to see that when it says -5, the actual value you're working with in code is 355. That's how a negative number can be greater than a positive. That's how you can take code that would be otherwise be working and make it do strange things.

    Realizing that even though they're both vector3, two rotations can actually be different types, and understanding the difference between unit vectors and Euler angles and when a method is asking for or returning one or another takes a lot of focus to keep track of, but has helped me immensely. It wasn't enough though, because then I had to stumble on the fact that there's (at least?) two ways of giving Euler angles, and I have no idea how many more ways to represent a rotation there are left to discover.

    Nothing else in Unity has given me so much trouble. I really despise angle and rotation math at this point. Surely there has to be a better way? This is so frustrating.
     

    Attached Files:

  2. halley

    halley

    Joined:
    Aug 26, 2013
    Posts:
    2,433
    You can't apply three Euler rotations at the same time, they must be applied in a given order, such as yaw then pitch then roll.



    This video goes to great lengths to help you choose a proper order of Euler rotations to avoid gimbal lock in various scenarios, but it points out there will ALWAYS be a gimbal lock problem if you're using Euler rotations.

    The true answer is Quaternions.

     
    Last edited: Mar 31, 2019
    lordofduct likes this.
  3. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,334
    The thing is, rotation is really hard. Unlike most everything else in everyday MonoBehaviour programming, it's a problem that's hard to model correctly (ie. it requires quaternions), and it's easy to get wrong.
    So don't get too frustrated that it's hard. It took me much longer to get comfy with rotations than with a bunch of other things.

    My advice is to stick to a single way of representing rotations within the same script. There are some times where you want to use facing directions (ie. Quaternion.LookRotation), there are some times you want to rotate around an axis (Quaternion.Euler()), and there are some (very rare) times where things align and you can just set the .eulerAngles directly. All of those work, and if you use the Quaternion wrapper methods, it's not that bad. It's when you start mixing those different ways of thingking about rotations that things go haywire - because then it gets hard to think about.
     
  4. Aeroxima

    Aeroxima

    Joined:
    Jul 19, 2016
    Posts:
    15
    Thanks, it helps a lot just hearing acknowledgment of it. In tutorials and teaching, everyone so far has just blown right past it like it was nothing. You need it so early on, it can make it feel like it's going to be a struggle to get every little thing going, if that's the baseline.

    I'll try to stick to something, but I wasn't sure there'd be a method for everything I needed in each "style" and I was just using whatever I found that seemed to fit the situation.

    I think it would have helped a lot if the inspector and code reported the same values though. I don't care which really, just that I can see its "actual value" in the inspector and base my code off of that (understanding the real actual value is a quaternion, but still).

    It would also help to not have the intellisense littered with deprecated stuff. Any way to hide these?