- Home /
Aplying all 3 axes on object like in inspector causes gimbal lock (different from other rotation problems),Rotate all angles of an Object to an specific angle cause gimbal lock
I have a script, that can give an object all axis of rotation simulat to the transform rotation x,y,z in the Inspector. So i want to instantly change the rotation to the degrees i give in the inputFields.
forExample
float x = float.parse(inputFieldX.text);
float y = float.parse(inputFieldY.text);
float z = float.parse(inputFieldZ.text);
...
void ApplyRotation(Transform object, float x,float y, float z){
object.eulerAngles = new Vector3(x,y,z);
}
but this causes in some cases the Gimbal Lock and Z and Y rotation does the same.
You are better off using quaternions. Gimbal lock doesn’t happen with Quaternions. It’s quite easy with the built in Unity functions to make the switch too
Answer by highpockets · May 03, 2020 at 10:24 PM
Ok, I’ll give a bit of an explanation so as to visualize how a quaternion works first. While working with Euler angles, we can visualize rotations quite easily, by just picking an axis (x,y,z) and assigning an angle in degrees to rotate and it’s that simple until you have to apply rotations to multiple axis at a time and this is when you can run into gimbal lock.
Quaternions on the other hand are much more flexible because you can escape from only having those three axis to work with and you can instead define your own axis. A quaternion takes 4 floats and the first 3 are the ones that define your axis. This is as simple as a direction vector. If you want to rotate around the y axis, the direction “before normalization” would be 0,1,0 or 0,-1,0. I say before normalization because quaternions are normalized in Unity (1 unit in length). The 4th float of a quaternion is the angle in radians which is 180/π degrees (so 0 to 1 radians is like saying 0 to 180 degrees in one direction and 0 to -1 Is like saying 0 to -180 degrees in the other direction where 1 and -1 are at the same orientation 180 degrees away from the initial orientation). Hope that makes sense.. So quaternions will always just give you the shortest route to arrive to the target orientation, ie: 270 degrees is just -90 degrees away from 0 degrees, so that would be -0.5 in radians. So a -90 degree rotation around the y axis would look like this (0,1,0,-0.5).normalized or (0,-1,0,-0.5).normalized depending on which axis direction we are referring to.
So after saying all that. Unity actually simplified working with quaternions so you don’t have to remake the wheel. In your case, I would think the best way to apply the rotations of each given angle to find your target angle would be the following:
//I am assuming we are working in the objects local space
float y = 40.0f;
float x = 180.0f;
float z = 5.0f;
Quaternion initialRot = transform.rotation;
transform.rotation = Quaternion.AngleAxis(y, transform.up);
transform.rotation = Quaternion.AngleAxis(x, transform.right);
transform.rotation = Quaternion.AngleAxis(z, transform.forward);
Quaternion targetRot = transform.rotation;
So as you can see you can just add degrees into the function and it will turn it into a Quaternion for you which is quite convenient. Now you have the initial rotation and the target rotation. If you want to do a smooth rotation to the target, you would have to reset and interpolate from one to the other. You can use Slerp, Lerp or RotateTowards.. Here is Slerp:
float timeScale = 0;
void Update(){
timeScale += Time.deltaTime;
transform.rotation = Quaternion.Slerp(initialRot, targetRot, timeScale);
if(timeScale >= 1.0f){
//reached the target rotation.
}
}
Hopefully that helps. Cheers
Great answer. Though a few error I'd like to correct:
The 4th component of a quaternion does not contain the angle in radians but the cosine of half the angle. Also note that the 4th component in Unity is usually the first one in the mathematical sense. So "w" is the real part while "x", "y" and "z" are the 3 imaginary parts.
Radians do not go from 0 to 1 to represent 0° to 180°. Radians just represent the arc length on a unit circle. So the arc length of a full unit circle (360°) is 2 * PI (or about 6.2832) while 90° are just PI / 2
The confusion might come from the cosine. So 0° will give you a "w" value of 1 since cos(0 / 2) == 1. However if the angle is 180° the cosine of half the angle would be "0"
Unit quaternions get their over all length from the unit vector in (x,y,z) and the fact that you multiply it by the sine of half the angle. So a 90° rotation around the up vector would be ((0,1,0)*sin(a/2), cos(a/2)) which would be about (0, 0.7071, 0, 0.7071). Keep in $$anonymous$$d that sin²(a) + cos²(a) == 1
always holds true
Apart from that, well explained ;) If you want to know more about how quaternions work behind the scenes mathematically I can highly recommend the Numberphile video on quaternions.
@Bunny83 Thanks for clearing that up. Ya my explanation on the angle was off like you said. Usually I would calculate the angle like so:
$$anonymous$$athf.Sqrt(Vector3.Dot(targetDirection, targetDirection) * Vector3.Dot(currentDirection, currentDirection)) + Vector3.Dot(targetDirection, currentDirection);
Where the target and current direction would be perpendicular to the rotation axis. There is the case where you can get 0 if you have exactly 180 degrees, but a check to see if current direction and target direction are the same will let you know if that is the case. Cheers
Your answer

Follow this Question
Related Questions
Why is rotation locking to an axis? 3 Answers
Pointing object at mouse using raycast only works when object is center screen. 2 Answers
How can I pitch and roll a circular platform without releasing vertical/horizontal input? 1 Answer
rotate a object around the x axis like other object... stucks at 90 degrees 2 Answers
Rotate one gameobject in 90 degree increments based on another gameobjects rotation. 0 Answers