- Home /
Quaternion.normalized
Hey there !
I have a dumb question. This line gives me "Input Quaternion was not normalized" error sometimes.
targetAngle = Mathf.Atan2(characterDirection.x, characterDirection.z) * Mathf.Rad2Deg + cameraRotation.normalized.eulerAngles.y;
Is there a known issue with the Quaternion.normalized property or am I using it the wrong way ?
Thanks for helping !
Why would you want to normalize the transforms quaternion presentation of rotation in the first place? Might be that I don't just know but to my understanding only if you do some direct quaternion manipulation you might end up in the situation where you need to normalize the quaternion value back to the correct limits.
To be completely honest I added the .normalized after seeing the error for the first time. The quaternion I use has been compressed before (I have some networking in my project) so even though the compression method should keep the quaternion normalized I thought it could help.
Ok, I really don't have an answer to this but you could check that what values rotation gives with Debug.Log. I think the magnitude of that Quaternion vector should be 1 or close to 1 and see if this has some correlation to the error message.. otherwise hopefully someone with more knowledge about this issue can help.
Just wanted to chime in to note that ANY Qaternerion generated by unity is a "Unit Quaternion", meaning, it is already normalized. I like to think of it as: Unit Quaternions specify an "orientation", rather than an "amount of rotation". The only way, that I know of, to get a NON-Unit Quaternion is to set the x,y,z,w coordinates of the Quaternion manually.
Yes, if the quaternion is going through an API by Unity (setting a transform rotation / localRotation) Unity will make sure the quaternion is normalized. However when you reconstruct a Quaternion manually, you have to take care about that yourself. The "normalized" property really does just normalize it the normal euclidean way.
Note that the constructor of the Quaternion struct does not force a normalization. Also oridnary quaternion multiplication does not force a renormalization. So if one of the quaternions is not a unit quaternion the result of a multiplication won't be normalized as well.
Answer by Bunny83 · Mar 07, 2021 at 09:29 AM
Well, if you transferred the quaternion over a network and reconstructed it on the other side, don't you think that including that piece of code would make more sense ? ^^. Quaternions in Unity are always normalized when you assign them to properties like localRotation or rotation since Unity only works with unit quaternions.
Have you actually pinned down the piece of code that is generating that error? Have you tried disecting that long line of code into seperate lines? That way it will tell you exactly on which line the error occurs. As CodesCove said there's usually no reason to normalize a Quaternion manually, at least not in the code you posted.
So try seperating your code into individual lines and tell us exactly on which line you get the error:
float angle = Mathf.Atan2(characterDirection.x, characterDirection.z) * Mathf.Rad2Deg;
Quaternion rot = cameraRotation.normalized;
targetAngle = angle + rot.eulerAngles.y;
Though as I said it would be more interesting where the original values come from instead of seeing where you use it.
Yes you are right. I assumed the error co$$anonymous$$g from cameraRotation not being correctly normalized since the rest of the line is using basic c# library (characterDirection.x/z can either be 1 or 0).
About the compression method, there are quite a few lines involved and I don't want to burden you with that. Just know that it is based on the "smallest three" method (you have some explanation here snapshot_compression).
I also want to say that most of the time I do not have any problem with it. I observed the error only about ten times in many hours of test.
Well, assu$$anonymous$$g characterDirection is a direction vector, the expression characterDirection.x/z
can actually be any real number from -infinity to +infinity. That's why Atan2 is such a great solution as it can handle almost any input without errors. The direction does not need to be normalized. Atan2 even handles the edge case 0/0 without an error (it just returns 0).
I'm not asking for sharing your whole transmission code since, as you said, this would be total overkill. However when you transmit the quaternion compressed it means you're loosing precision which most likely will result in the resulting quaternion not being normalized anymore as the magnitude of the quaternion probably isn't exactly 1 anymore. So it would be important to know, after uncompressing your 4 values, how do you turn them back into a unit quaternion? If there's an issue in your unpacking code it may be useful to add some logging to the receiving code and log the reconstructed quaternions alongside unity's warning message in order to inspect the actual values.
The beauty about the "smallest three" is that you only send 3 of the 4 properties of a Quaternion. The last one which is the biggest is then calculated on the receiving end knowing that the magnitude should equal 1. I think what I truly want to understand here is :
If my quaternion Q is not correctly normalized, will Q.normalized return something i can use ?