|
I have a script that limits the rotation of an object, which can be set in the inspector with any min/max value. This works as long as my rotation min/max values are positive, but breaks with negative values. So for example, limiting rotation between -45 and 45 degrees breaks. The problem I know has to do with euler angles, since they don't have negative values. A negative number x is converted to 360-x. I suspect I can get around this using quaternions, but I don't really know how to do it. I need to read the X, Y and Z rotation values (the same values displayed in the Transform) and then apply the min/max limits. Anybody understand quaternions well enough to point me in the right direction?
(comments are locked)
|
|
I'm going to answer my own question with the solution I found, but it's a bit less than ideal. I could find no way to get negative euler rotation values from quaternions. Somehow Unity is doing it in the Transform inspector, but I can't figure out how (maybe it's a UI trick). So instead, I'm offsetting my limit calculations so they always occur between 0 and 360. For example, with a rotation limit of -45 to 45, I'm offsetting the input values by 45 so the range calculated is 0 to 90, then offsetting it back -45. This solution works fine for rotation limits with a span less than 360 degrees.
(comments are locked)
|
|
The rotations are always stored as Quaternion. Quaternions doesn't even work with angles in degree. A Quaternion defines a 3D-rotation as one thing and not like eulerAngles with 3 consecutive rotations. It describes the rotation by a 3D rotation-axis-vector and another float value that describes the rotation around that axis. But they work with normalized complex numbers and you can't work with them like you're used to (the euler-angles-representation) This is the original inspector for the Transform component. As you can see the rotation that you see in the inspector is the Vector3 that is returned by localEulerAngles. However if the rotation is affected by the physics-system it can clamp the values or two of them jump by 180° when it would run into a gimbal-lock. There's no much you can do about that. Well, it depends on your case. If you have full control over the rotation you can use a Vector3 to store the 3 angles and use Quaternion.Euler to convert them into a rotation. Thanks for this thorough reply! There's one thing I still don't understand about the Transform inspector. How does this line work? this.rotation = EditorGUILayout.Vector3Field("Rotation", this.rotation, new GUILayoutOption[0]); It seems to me this is wrong... shouldn't it be localEulerAngles, since rotation is Quaternion? And is it just a UI trick that negative numbers are displayed? If the UI is just storing the float values entered by the user, it could be converting them under the hood to euler angles while still preserving the appearance of negative values.
Sep 22 '11 at 02:12 AM
Steven Walker
rotation inside the TransformInspector is defined as So it's not really a trick by the UI. It's a trick by the Transform itself but only for the UI. The conversion from quaternion into eulerangles which happens at runtime will always return positive angles.
Sep 23 '11 at 01:12 AM
Bunny83
That makes sense. Thanks for the extra explanation.
Sep 23 '11 at 06:06 AM
Steven Walker
(comments are locked)
|

One other note... I really need to work with negative values because there may be cases where I want limits to be something like -360 to +360, which means the object should be able to rotate one full turn each direction and not any further. Euler angles would oversimplify this and allow the object to rotate continuously.