I'm trying to make a simple flight simulator, and I tried to get the a pitch value(x of the rotation) of the plane. I thought it will work if I get the x value of the rotation by
transform.rotation.eulerAngles.x
and I tried other code that changes quaternion to euler angle.
but the value starts to act strangly. when I change x value to something greater than 90,, the value starts to decreases and y and z values changes change higher by 180. I think this is something like anti-gimbol lock system, but I don't know how get the original value.
CodePudding user response:
See eulerAngles
When using the .eulerAngles property to set a rotation, it is important to understand that although you are providing X, Y, and Z rotation values to describe your rotation, those values are not stored in the rotation. Instead, the X, Y & Z values are converted to the Quaternion's internal format.
When you read the .eulerAngles property, Unity converts the Quaternion's internal representation of the rotation to Euler angles. Because, there is more than one way to represent any given rotation using Euler angles, the values you read back out may be quite different from the values you assigned. This can cause confusion if you are trying to gradually increment the values to produce animation.
In short: eulerAngles
returns just one simplified human readable way of writing your current Quaternion
value.
From here I made some extension methods you could use
public static class QuaternionExtensions
{
public static float Pitch(this Quaternion q) => Mathf.Rad2Deg * Mathf.Atan2(2 * q.x * q.w - 2 * q.y * q.z, 1 - 2 * q.x * q.x - 2 * q.z * q.z);
public static float Yaw(this Quaternion q) => Mathf.Rad2Deg * Mathf.Atan2(2 * q.y * q.w - 2 * q.x * q.z, 1 - 2 * q.y * q.y - 2 * q.z * q.z);
public static float Roll(this Quaternion q) => Mathf.Rad2Deg * Mathf.Asin(2 * q.x * q.y 2 * q.z * q.w);
}
so you could do
var q = transform.rotation;
var pitch = q.Pitch();
var yaw = q.Yaw();
var roll = q.Roll();