- Home /
Rotation Problem - Simulating Gimbal lock
I'm Having a problem with rotations. I've done some research about this problem but it seems that everyone solves it with rotateArround. I'm trying to replicate the rotations of a SpaceShip on a graphic representation. For that, I have to replicate its rotation on X, Y and Z on another object. My object 1 is a gray cube and object two is a Colored cube with other cubes in it.
The red represents X. The green represents y. The blue represents z.
When I rotate cube 1 on X axis, the cube two red (and its children) should rotate the same amount. The Y and Z work ok but the X is big problem.
In the end - the lowest cube on the hierarchy should be on the same position that the reference object.
The problems are: -x only rotates between [270, 90] and after that the cube rotates in a weird way. - when I copy the rotation values using quaternions the W recalculates automatically and I can't copy on only one axis.
The CODE:
if (xBool) {
transform.localEulerAngles = new Vector3 (originalObj.localEulerAngles.x, transform.localEulerAngles.y, transform.localEulerAngles.z);
}
if (yBool) {
transform.localEulerAngles = new Vector3 (transform.localEulerAngles.x, originalObj.localEulerAngles.y, transform.localEulerAngles.z);
}
if (zBool) {
transform.localEulerAngles = new Vector3 (transform.localEulerAngles.x, transform.localEulerAngles.y, originalObj.localEulerAngles.z);
}
Can someone help me?
thank you for your time!
Some Unity rotation functions and angle based stuff tend to work up to 180 degrees. Working in Euler in Unity is a dangerous thing in general and you should consider contructing a quaternion out of your rotational information. Look at Quaternions in the Scripting API. You will find you can modify a quaternion using euler if you need.
Unity sometimes cant decide if its 90 or -270 etc. You need to add some data conditioning to your degrees before you use the data.
if(degrees < 0) //This kind of thing.
{ degrees += 360; }
Sorry if Im of no help whatsoever.
Thank you for your help! I tried to make some degree ajustments make it all turns out in a big unprecise mess.
If I rotate the 360 it turns out the same.
The problem with the rotation is that the original object can rotate normally but when it passes the 90 degrees it changes it reference (changes y and z to 180) and the "replica" maintains its original reference
@meat5000
Euler angles are fine for representing rotations; there's nothing that "dangerous" about them. Adding 360 to any angle in the Euler angle won't change anything. Unity does that to keep Euler angles within a certain range. Euler angles only start to fail when you try to interpolate them the way you would vectors.
For example, let's say you take a vector pointing in the positive x axis, rotate it about the z axis by 90 degrees so that it points up. At this point, you can do any rotation about the y axis and the vector would be the same (gimbal lock). That is, the Euler angle (0, 0, 90) is the same as the Euler angle (0, 180, 90) and is the same as (0, y, 90) for any value of y.
What would happen if you wanted to interpolate the Euler angle (0, y, 90) with (0, 0, 0)? For (0, y, 90), the vector in the above example points up, and for (0, 0, 0) the vector points right. In the "correct" interpolation, at the half way point, the Euler angle of the vector should be (0, 0, 45). However, if you actually interpolate the two Euler angles, you would get the Euler angle (0, y/2, 45) ins$$anonymous$$d, which will only give the "correct" result when y = 0.
To obtain the correct interpolation, you would need to do a bit more work. If we have two vectors and we want to rotate one to the other, we can obtain the angle between the two vectors by dotting them. Then, we rotate the first vector by a fraction of that angle, about the axis that is perpendicular to the two vectors (obtained using the cross product). You don't actually have to do this, since using quaternions will handle this.
@sadsa
I think your problem might be caused by using localEulerAngles ins$$anonymous$$d of eulerAngles. If you rotate the parent, the children automatically rotate with it. If you set the local Euler angles of the children to the parent's Euler angles, then the children will perform the parent's rotation twice: once from the parenting, and once from setting the local Euler angles.
You might be right. There must be a problem with the hierarchy but I tried every combination of localEulerAngles, eulerAngles.. and the Z rotation works fine, but the other two do not.. I deleted the hierarchy and done it all again.
void Update () {
if(x){
transform.rotation = Quaternion.Euler(targetCube.eulerAngles.x, transform.eulerAngles.y, transform.eulerAngles.z);
}
if(y){
transform.localRotation = Quaternion.Euler(transform.eulerAngles.x, targetCube.eulerAngles.y, transform.eulerAngles.z);
}
if(z){
transform.rotation = Quaternion.Euler(transform.eulerAngles.x, transform.eulerAngles.y, targetCube.eulerAngles.z);
}
}
}
with the hierarchy :
I think this is giving me the global rotation of the target ins$$anonymous$$d of the local rotation. The problem should be here: targetCube.eulerAngles.x
how can I correct this?
(THAN$$anonymous$$ YOU SO $$anonymous$$UCH FOR SPENDING THE TI$$anonymous$$E TO REPLY! and sorry for my bad english)
Answer by cjdev · Oct 04, 2015 at 07:09 AM
Instead of editing the localEuler angles directly I believe you can avoid Gimbal Lock by using Unity's built in Euler function:
transform.rotation = Quaternion.Euler(originalObj.localEulerAngles.x, transform.localEulerAngles.y, transform.localEulerAngles.z);
Your answer
Follow this Question
Related Questions
Why is this rotation not performed as expected? 1 Answer
rotation with eulerangles and raycasting. 1 Answer
Quaternion reset rotations didnt smooth 0 Answers
Rotate object based on set time. 2 Answers
Proper way to rotate an object? 1 Answer