Search Unity

Difference between UnityEngine.Quaternion and Unity.Mathematics.quaternion

Discussion in 'Entity Component System' started by Reloque, Nov 13, 2019.

  1. Reloque

    Reloque

    Joined:
    Apr 28, 2015
    Posts:
    207
    So, I was coding some simple direction rotation stuff like this;
    Code (CSharp):
    1. rotation.Value = Quaternion.Euler(0, 0, 90);
    And that worked, hard 90 degrees corner on my sprite. Somewhere else I had;
    Code (CSharp):
    1. rotation.Value = quaternion.Euler(0, 0, 90);
    And that didn't work. Having an actual rotation of about 0.85 on the z instead of the 0.70 or so I'd expect. Now, Quaternion, is from UnityEngine and quaternion is from Unity.Mathematics. Is that intentional, did I stumble upon something strange or don't I understand quaternions yet again.
     
  2. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,685
    Because quaternion.Euler expects radians, not degrees
    upload_2019-11-13_16-47-38.png
     
    IrvineLee, deab, starikcetin and 3 others like this.
  3. Reloque

    Reloque

    Joined:
    Apr 28, 2015
    Posts:
    207
    Okay, that does solve some part. Thanks. The other question is somewhat related; why is turning towards another object not working;

    Here is the thing. I build a simple turn toward script, doing all the work manually. Now, i'd like to simplify this, using code from the Unity example video, this bit;


    Code (CSharp):
    1. Entities.ForEach((ref Translation translation, ref Target target, ref Rotation rotation) =>
    2.         {
    3.             float3 heading;
    4.             translation.Value = new float3(0f, 0f, 0f);
    5.             target.Value = new float3(10f, 10f, 0f);
    6.             heading = translation.Value - target.Value;
    7.             rotation.Value = quaternion.LookRotation(heading, math.up());
    8.         });
    For test purposes hard coded, I'd expect the object at 0,0,0 to turn 45 degrees towards the target at 10,10,0.
    However, no such thing happens. Instead I get rotations on the x and y while I'd expect only on the z.
     
  4. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,685
    First - use LookRotationSafe. Second check where you object forward looks.
     
  5. Reloque

    Reloque

    Joined:
    Apr 28, 2015
    Posts:
    207
    Thanks.

    The first part I can do, the second, what does that mean? The object is a flat sprite, I I rotate by "hand" and convert and set the z that way, it works. But using LookRotationSafe doesn't change anything. It sill doesn't rotate like i'd expect.
     
  6. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,685
    LookRotationSafe works as expected, without problems. Show your entity in debugger and your pre-conversion setup.
     
  7. Reloque

    Reloque

    Joined:
    Apr 28, 2015
    Posts:
    207
    Okay, step back maybe;

    This is code that works;
    Code (CSharp):
    1. Entities.ForEach((ref Translation translation, ref Target target, ref Heading heading) =>
    2.         {
    3.  
    4.             float baseX, baseY;
    5.             float targetX, targetY;
    6.             Vector2 origin, goal, orientation;
    7.             float angle;
    8.  
    9.             baseX = translation.Value.x;
    10.             baseY = translation.Value.y;
    11.  
    12.             targetX = target.Value.x;
    13.             targetY = target.Value.y;
    14.  
    15.             origin = new Vector2(baseX, baseY);
    16.             goal = new Vector2(targetX, targetY);
    17.  
    18.             orientation = goal - origin;
    19.             angle = Vector2.SignedAngle(Vector2.down, orientation);
    20.  
    21.             var x = orientation.x;
    22.             var y = orientation.y;
    23.  
    24.             float value = (float)((Mathf.Atan2(x, y) / Mathf.PI) * 180f);
    25.             if (value < 0) value += 360f;
    26.  
    27.             angle = value;
    28.  
    29.             heading.Value = angle;
    30.         });
    Combined with this bit;

    Code (CSharp):
    1.         Entities.ForEach((ref Rotation rotation, ref Heading heading ) =>
    2.         {
    3.             Quaternion currentRotation = rotation.Value;
    4.             float3 eurlerRotation = currentRotation.eulerAngles;
    5.  
    6.             float newRotation = heading.Value;
    7.  
    8.             // correct for strange Quaternion stuff, why is 45 mirrored?
    9.             newRotation = 360 - newRotation;
    10.  
    11.             rotation.Value = Quaternion.Euler(0, 0, newRotation);
    12.  
    13.         });
    I'd hope to replace that with more concise and clearer code, but the example I posted doesn't work and gives me this;

    upload_2019-11-14_12-22-53.png
     
  8. elcionap

    elcionap

    Joined:
    Jan 11, 2016
    Posts:
    138
    You don't need to use the Quaternion to use degress, just use this:

    Code (CSharp):
    1. rotation.Value = quaternion.Euler(math.radians(new float3(0, 0, 90)));
    For LookRotation, it didn't work because your vector is not normalized. LookRotationSafe will not only normalize your vector but when the result is invalid, it will return an identity value.

    IMHO that's the best part of the math package. You are not wasting operations normalizing a already normalized vector. Or having to convert an value in radians to degrees just to be converted to radians again.

    About your result in rotation, they are correct. You are expecting the look using the X as a forward when is Z.

    []'s
     
  9. Reloque

    Reloque

    Joined:
    Apr 28, 2015
    Posts:
    207
    Okay, I believe I understood, but I tried your code line;

    Code (CSharp):
    1.  
    2. Entities.ForEach((ref Translation translation, ref Target target, ref Heading heading, ref Rotation rotation) =>
    3.         {
    4.             rotation.Value = quaternion.Euler(math.radians(target.Value));
    5.         });
    6.  
    7.  
    But that doesn't do anything. As in the rotation value never gets changed. When I log the value, it gets changed, in the debugger it does change. But, in the game window itself, it doesn't rotate the sprite at all.