Hi there,

I am adjusting the z of a localEulerAngles. Generally I am shifting between 345 and 15 degrees. My issue is when I cross 0. At this point, the transform tends to flip about.

Any suggestions?

Hi there,

I am adjusting the z of a localEulerAngles. Generally I am shifting between 345 and 15 degrees. My issue is when I cross 0. At this point, the transform tends to flip about.

Any suggestions?

Have you read the answer to this question?

Sounds like youâre running into something called Gimbal Lock which is the reason Game Development uses Quaternions in the first place. To get around the problem try using Quaternion.Euler instead.

Gimbal lock would happen when you rotate one axis over another, not just about an axis, and once in the locked position any adjustment to that angle would result in no changeâŚ not âflipping aboutâ.

In the same respect, OP doesnât exactly describe what âflip aboutâ even means. Or if theyâre doing any other rotations around other axes. So they may actually be having gimbal lock and they just didnât give us enough information. Of course, Quaternion.Euler doesnât necessarily fix this since thatâs just using euler angles. The âeulerAnglesâ and âlocalEulerAnglesâ properties are just wrappers around Quaternion.eulerAngles and Quaternion.Euler.

From decompiled âTransformâ source code:

```
/// <summary>
///
/// <para>
/// The rotation as Euler angles in degrees.
/// </para>
///
/// </summary>
public Vector3 eulerAngles
{
get
{
return this.rotation.eulerAngles;
}
set
{
this.rotation = Quaternion.Euler(value);
}
}
/// <summary>
///
/// <para>
/// The rotation as Euler angles in degrees relative to the parent transform's rotation.
/// </para>
///
/// </summary>
public Vector3 localEulerAngles
{
get
{
Vector3 vector3;
this.INTERNAL_get_localEulerAngles(out vector3);
return vector3;
}
set
{
this.INTERNAL_set_localEulerAngles(ref value);
}
}
```

(localEulerAngles does an internal call because it has to decompose its rotation from the global rotation through the parent tree, and itâs faster to do in C++ than in C#)

As for OP, still not sure what you mean by âflip aboutâ, but itâs probably because you are using euler angles (just because itâs using euler angles, doesnât mean gimbal lock, gimbal lock isnât the *only* issue with euler angles). It does happen when you cross the 360 line which flips back to 0.

Instead of using eulerAngles to increment rotate around the z-axis, instead increment the quaternion:

```
transform.localRotation *= Quaternion.AngleAxis(30f, Vector3.forward); //rotate 30 degrees around the z axis
```

According to the docs Quaternion.Euler rotates in a specific order every time which is not the same as modifying Euler angles individually. If you had two of the values at 0 you effectively have an AngleAxis rotation around one of the major axes.

yes, if you did:

```
transform.localRotation *= Quaternion.Euler(0f, 0f, 30f);
```

But itâs not the using Quaternion.Euler that would do that, itâs the incrementing via Quaternion. I was making that distinction because you said itâs gimbal lock (which it isnât) and that the answer is to use Quaternion.Euler, but didnât explain in what manner to use Quaternion.Euler. The OP could easily have used it to SET the rotational valueâŚ which really is all âTransform.eulerAnglesâ does in the first place.

Case in point, the source code I posted.

All Quaternion.Euler does is give you the amount of rotation from origin to that orientation. Which is useful. And can work just fine if you want to create a ân degrees around standard axis x,y, or zâ. But itâs rigid and conforms to only those axes in that rotational orderâŚ I prefer the AngleAxis as it allows for pretty much any rotational direction in a human readable formâŚ while being consistent. Otherwise when Iâm rotating around the z axis, Iâm using â.Eulerâ but when I rotate around <1,1,1> Iâm using â.AngleAxisâ. Eh, why mix it all up like that.

Thanks all for the feedback.

In my case, since I am in total only rotating 30 degrees, 15 in one direction, 15 in the other. Since I am not needing to cover 360 + degrees, I have come up with a very simple solution.

Keeping my code to adjust the localEulerAngles, the parent transform I am rotating, I simply offset its rotation by 90 degrees at start. As such, I never cross the dreaded zero!!

Works like a charm.

Cheers!

1 Like