Search Unity

How to fix quaternion lookrotation error

Discussion in 'Scripting' started by Velo222, Sep 16, 2013.

  1. Velo222

    Velo222

    Joined:
    Apr 29, 2012
    Posts:
    1,437
    Hello,

    I am getting this error in Unity:

    !CompareApproximately (det, 1.0F, .005f)
    UnityEngine.Quaternion:LookRotation(Vector3)


    In my code I'm doing this:
    Code (csharp):
    1. //if ( arrowDir != Vector3.zero) {
    2.         //The arrow was pointing ~90 degrees in the wrong direction, so this is to adjust for it
    3.         //This is the Euler direction the arrow should look
    4.        _lookRotation = Quaternion.LookRotation(arrowDir)*Quaternion.Euler(0, 90, 0);
    5.     //}
    I have a feeling it has to do with the fact that I'm multiplying the LookRotation by the Euler angle, but I'm not sure how to fix this? I get the direction and angle I want, but it throws that error and slows my game to a halt. I'm also wondering what the "det" means in the error?

    Thanks for any help.
     
  2. halley

    halley

    Joined:
    Aug 26, 2013
    Posts:
    2,447
    It's the Euler angle (pronounced oiler). Euler angles are pleasant to work with if your rotations are very simple, but they have a major shortcoming when trying to rotate anywhere near the poles of a theoretical sphere. See, if you get close to a pole, it's hard to tell whether you turned around the X axis to get there, or around the Y axis, or around the Z. This is a mathematical singularity, and it's called gimbal lock.

    If you were working with just Quaternions, you would not have any problem with gimbal lock. If you are converting a set of Euler angles to a Quaternion, it must compute what contribution each angle has to an axis direction and twist amount. One step of the calculation is to find a determinant, which is basically a number that describes the solvability of a series of equations. However, for an unsolvable series you might be getting a determinant of "who the heck knows," a value called NaN which stands for Not a Number. It's like dividing by zero-- it just can't come up with a single reasonable answer, so it gives up. Unity3d will slow down because it's constantly throwing an exception and logging this mathematical puzzle.

    Explain in more detail what you're trying to do, and maybe we can help with an all-Quaternion or all-simple-vector mathematical way to achieve it. If you're correcting by 90 degrees, a simple cross-product probably will get what you want.
     
  3. Velo222

    Velo222

    Joined:
    Apr 29, 2012
    Posts:
    1,437
    Hi halley,

    That is great information to know, thank you. I will try to explain a little more what I'm doing then.

    I'm basically instantiating an arrow gameobject (call it arrow2) at a certain position relative to my "archer" unit. The arrow2 is basically placed upon the arrow1 (via transform.position) right before the archer "fires" arrow1. After the animation runs where the archer "releases" arrow1, I translate arrow2 to the enemy target. While arrow2 is translating, I'm also constantly rotating arrow2 to point at the enemy target (granted I'm doing this in the Update function, I thought about trying it in the FixedUpdate function). So it's having to do the rotation calculation extremely fast.



    Edit: I didn't fix the problem directly, but I added in a few more conditionals in my "if" statement for the lookrotation code, and that seemed to fix it. So it works now without errors, however it's not a perfect fix.
     
    Last edited: Sep 16, 2013
  4. Elpresley

    Elpresley

    Joined:
    Jun 6, 2020
    Posts:
    1
    In my code i use this but it is not working
    Code (CSharp):
    1. if (movement.magnitude > 0)
    2.         {
    3.             Quaternion newDirection = Quaternion.LookRotation(movement);
    4.  
    5.             transform.rotation = Quaternion.Slerp(transform.rotation, newDirection, Time.deltaTime * turnSpeed);
    6.         }
     

    Attached Files: