Hey guys,
I have been debugging and I found something that is causing issues.
Basically, my script instantiates an object on the ground surface (raycast) then once it’s there, I save it’s position and euler rotation to a string for later. My problem, is when I use that string again to form a quaternion for another instantiate, the object get’s placed where it should be, but I now get two different euler rotation values from it. In the inspector it is high numbers, from script it is like 6.1, 5.8, 6.3 and that is NOT what was originally set. (the position part of this works perfectly btw).
Confusing I know, and I have a good reason for doing it with strings and all. The annoying thing is it works fine, but it screws with the numbers, and I need those later. I tried copying the raw quaternion data (x,y,z,w) since it was going to be assembled the exact same way again anyhow, but that threw a lot of iCompare quaternion errors no matter what I did.
Is this an issue with euler angle accuracy, a bug, or am I doing something wrong?
EDIT: Oh, forgot to mention, my script as-is works perfectly for more than half of the objects. There are just a few random ones where the values get changed.
Thanks guys,
-Jeremy
How are you extracting the euler angles and how are you setting it back?
I think the euler angle conversion functions are pretty robust by now.
I am forming the string with myRotation.ToEulerAngles()
I then create a new blank quaternion, then set it to the euler angles I got before:
Quaternion rot = new Quaternion();
rot = Quaternion.EulerAngles(x,y,z)
What confuses me, is that it works SOME of the time. It will properly give the rotation for most of the objects, but there are random ones where it doesn’t. And the values are far different in the inspector than what I get from code. (EDIT: yet the objects still get positioned in the right place.)
-Jeremy
Quaternion.EulerAngles returns the angles in radians.
Where as transform.eulerAngles returns the angles in degrees.
Damn, that makes sense thanks… How can I get around it as I see there is no quaternion method to return euler angles in degrees? When I built the quaternion “manually” from the same x,y,z,w components I had errors out my ears.
EDIT: And why would this still work some of the time? I have been using the rotation string basically as an ID for the object and it works for most?
Thanks Joe,
-Jeremy
Multiply the value with Mathf.Rad2Deg or Mathf.Deg2Rad.
If you want to robustly compare two rotations you can NOT use euler angles.
This is due to floating point precision and gimbal lock. When comparing positions, floats or rotations you always need to check the distance between the two and compare against some epsilon value:
The following C# functions gives you the angle between two quaternions in degrees. You can compare it against say 1 to test if two quaternions are 1 degree apart.
static public float AngleBetween (Quaternion a, Quaternion b)
{
float dot = Quaternion.Dot(a, b);
return Mathf.Acos(Mathf.Min(Mathf.Abs(dot), 1.0F)) * 2.0F;
}
I tried the Deg2Rad and Rad2Deg and both totally screwed up my rotations, it was either all normalized or screwed depending which one I used. I would rather not go into the angle check as it is slight overkill for my code, I just wanted to identify that specific object quickly and accurately, and everything is somehow already being positioned perfectly, but thanks a lot for the code. I will just have to rewrite my code to not check against the rotation… Lol I spent a lot of time getting that working too… Ironic.
Thanks,
-Jeremy
You are probably multiply the quaternion. Of course you should only multiply the euler angles with this.
But why dont you just use transform.eulerAngles instead. That will give you the right value with the angle in degrees.