Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Check if Quaternion hasn't been modified

Discussion in 'Scripting' started by DroidifyDevs, Jun 25, 2017.

  1. DroidifyDevs

    DroidifyDevs

    Joined:
    Jun 24, 2015
    Posts:
    1,724
    Hello!

    I've run into a bummer (I'm probably not understanding something here). Basically, I'm making a simply AI script, and I'm adding an offset to a target rotation like this:

    Code (CSharp):
    1. TargetRotation = Quaternion.LookRotation(Heading);
    2.         TargetRotation *= AvoidanceOffset;
    However, if I haven't set AvoidanceOffset to anything, Quaternion.LookRotation seems to have no effect and the object doesn't rotate. So I decided to do this:

    Code (CSharp):
    1. if(AvoidanceOffset != Quaternion.identity)
    2.             TargetRotation *= AvoidanceOffset;
    That way if I hadn't set AvoidanceOffset to anything, it wouldn't try to add it. However, the if statement is never triggered.

    So I took it an extra step:
    Code (CSharp):
    1. if(AvoidanceOffset != Quaternion.Euler(0, 0, 0))
    2.             TargetRotation *= AvoidanceOffset;
    Yet the inspector shows AvoidanceOffset to be 0, 0, 0, 0.

    So my question is, how can I check if a Quaternion is = to 0, 0, 0, 0?

    Thank you!!
     
    Reahreic likes this.
  2. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
  3. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,513
    What's it matter.

    If AvoidanceOffset wasn't set, the multiplication of it will result in no change... if it was, it will change. Isn't that expected behaviour?
     
  4. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Not sure if you're talking to me or the OP, but Quaternion.identity = { 0, 0, 0, 1 } is why I posted my link.
     
    DroidifyDevs likes this.
  5. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,513
    Talking to OP.
    (I'm operating under the idea that AvoidanceOffset is a serialized field, which would mean 'not-set' would make it the identify quaternion from the get go, since that's the default quat value when unity deserializes... but yes, if it's not serialized, then they should be setting it to identity from the get go)
     
  6. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Yep, honestly I didn't really know the answer and thought as much as you. I didn't even know identity meant 0,0,0,1 until I looked it up - but posted because he said to compare to 0,0,0,0 :)
     
  7. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,513
    Also, at OP... if you've got an actual zero quat, and that's what you want to rule out.

    Either a default(Quaternion) or constructing a zero Quaternion will work (new Quaternion(0f,0f,0f,0f)):
    https://docs.unity3d.com/ScriptReference/Quaternion-ctor.html

    Though honestly, having a zero quat means either you setup your scenario incorrectly, or you did some maths that screwed things up really bad.
     
  8. DroidifyDevs

    DroidifyDevs

    Joined:
    Jun 24, 2015
    Posts:
    1,724
    A quick Debug.Log tells me Quaternion.Identity is 0,0,0,1, so that's my bad.

    Thanks for the help! Turns out that my assumption that Quaternion.Identity was 0,0,0,0 was the problem. I simply did this:
    Code (CSharp):
    1. if (AvoidanceOffset != Quaternion.identity)
    2.             TargetRotation *= AvoidanceOffset;
    3.         else
    4.             Debug.Log("EQUAL!");
    And set AvoidanceOffset in the Inspector to 0,0,0,1:
    upload_2017-6-25_16-16-38.png

    And it works great :D
     
  9. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,513
    But why even bother?

    Multiplying by the identity quaternion is like multiplying 5 by 1... you still get 5. It's why it's called the 'identity' vector.

    You should be able to just get away with:
    TargetRotation *= AvoidanceOffset

    And why is your inspector showing the quat as its imaginary parts... why is it not showing as euler? Do you expect people to set the actual quaternion values? I'm good with quats, and I don't even want to have to sit down and do the maths to calculate the appropriate values for x,y,z,w.
     
    DroidifyDevs likes this.
  10. DroidifyDevs

    DroidifyDevs

    Joined:
    Jun 24, 2015
    Posts:
    1,724
    You're completely right. Because I set AvoidanceOffset to 0,0,0,0, it wasn't rotating. So I thought that 0,0,0,0 was Quaternion.Identity and that somehow was causing it to not rotate. As soon as I set AvoidanceOffset, the 4th number becomes non-zero and it would rotate properly.

    Therefore, I didn't even need this if I had simply set it correctly the first time. I took out the if statement and it behaves the same.

    Can I make the Inspector show Euler angles? I'd love that; it always shows me non-Euler angles for Quaternions.

    Thank you for pointing that out, I learned something new today!
     
  11. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,513
    Sorry, my bad. I'm so used to my framework that I forgot that Unity doesn't use a euler inspector by default for Quaternions.

    Bad Unity, bad!

    But yeah, I use a custom PropertyDrawer for my Quaternions always. Cause srsly, the values of a quat are unintelligible to the average user.

    Here's the actual field code:
    https://github.com/lordofduct/space...ster/SpacepuppyBaseEditor/SPEditorGUI.cs#L747

    And the PropertyDrawer I use:
    https://github.com/lordofduct/space...ctors/EulerRotationInspectorPropertyDrawer.cs

    There's other's with less dependencies out there... like here's a really simple one:
    http://answers.unity3d.com/questions/1314080/use-euler-angles-for-quaternion-variable-in-the-in.html
     
  12. DroidifyDevs

    DroidifyDevs

    Joined:
    Jun 24, 2015
    Posts:
    1,724
    Whenever I've needed to know the angles of something I just spam the Console. Awful but simple.

    Some things just baffle me with Unity. They show Euler angles in the Transform component, but they can't show them in your scripts? That's either extreme laziness or bad coding.

    I'll definitely check out the Spacepuppy framework since Quaternion Euler angles in the Inspector would be a great feature to have. Maybe Unity will buy it like they did with TextMeshPro ;)
     
  13. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,513
    Oh, don't take this entire framework just to get euler angles in the editor, like I said, there's simpler ones out there which I linked.

    I actually have to do some pruning to this framework... over the years it has gained some things that turned out we NEVER use. Just haven't had the time to do the refactoring since we're in the midst of developing.
     
    DroidifyDevs likes this.