Skip to content

Commit 3bde1ca

Browse files
committed
improve euler angles
1 parent 400f7fd commit 3bde1ca

1 file changed

Lines changed: 66 additions & 10 deletions

File tree

docs/basics/euler-angles.md

Lines changed: 66 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,74 @@
11
# Euler Angles
22

3+
Euler angles describe rotations with three ordered rotations (typically yaw, pitch, roll) expressed in degrees. Unity exposes them heavily in the Inspector, but under the hood it converts every change to quaternions. Treat Euler angles as a user-friendly façade: lean on them for authoring and quick edits, then hand off to quaternions for math-heavy work.
4+
5+
## Where Euler Angles Shine
6+
7+
- Editing rotations in the Inspector or scripting quick adjustments in degrees.
8+
- Presenting player-facing data such as compass bearings or camera pitch.
9+
- Constraining motion to specific axes (e.g., yaw-only turrets, clamped camera pitch).
10+
- Debug logging of orientation values without converting radians to degrees.
11+
12+
## Reading and Setting Euler Values
13+
314
```csharp
4-
// Euler angles are "degree angles" like 90, 180, 45, 30 degrees.
5-
// Quaternions differ from Euler angles in that they represent a point on a Unit Sphere (the radius is 1 unit).
15+
// Grab the world rotation in degrees
16+
Vector3 worldEuler = transform.eulerAngles; // e.g., (0, 180, 0)
17+
18+
// Override the yaw while keeping existing pitch/roll
19+
Vector3 newEuler = worldEuler;
20+
newEuler.y = desiredHeadingDegrees;
21+
transform.eulerAngles = newEuler;
622

7-
// Create a quaternion that represents 30 degrees about X, 10 degrees about Y
8-
Quaternion rotation = Quaternion.Euler(30, 10, 0);
23+
// Local rotation in degrees, relative to the parent
24+
Vector3 localEuler = transform.localEulerAngles;
25+
transform.localEulerAngles = new Vector3(0f, 45f, 0f);
26+
```
27+
28+
Euler angles wrap to the range `[0, 360)` when read from Unity. If you need values centered around zero, normalize them manually with helpers like `Mathf.DeltaAngle`.
29+
30+
## Creating Quaternions From Euler Data
31+
32+
```csharp
33+
// Construct from components (XYZ order, degrees)
34+
Quaternion facing = Quaternion.Euler(0f, 30f, 0f);
35+
36+
// Construct from a vector
37+
Vector3 turretAngles = new Vector3(0f, 90f, 0f);
38+
Quaternion turretRotation = Quaternion.Euler(turretAngles);
39+
40+
// Mix: set pitch in Euler, keep yaw from a quaternion
41+
Quaternion baseRotation = transform.rotation;
42+
Vector3 mixedEuler = baseRotation.eulerAngles;
43+
mixedEuler.x = pitchDegrees;
44+
transform.rotation = Quaternion.Euler(mixedEuler);
45+
```
46+
47+
Under the hood Unity uses Z-X-Y (roll, pitch, yaw) order when converting Euler angles to quaternions. You usually do not need to care, but remember that reordering axes changes the final orientation.
48+
49+
## Avoiding the Common Pitfalls
50+
51+
- **Gimbal lock** – When two axes align, you lose a degree of freedom. This happens when composing Euler rotations directly; generate a quaternion via `Quaternion.Euler` and combine in quaternion space instead.
52+
- **Interpolation artefacts**`Vector3.Lerp` on Euler angles causes axis flipping near 180/360°. Prefer `Quaternion.Slerp` or `Quaternion.Lerp` for smooth motion.
53+
- **Angle wrapping** – Values jump between `0` and `360` instead of smoothly crossing through zero. Use `Mathf.DeltaAngle`, or track your own unbounded angle accumulator.
54+
- **Inspector edit order** – Rotations apply in Z-X-Y order. Animating multiple axes simultaneously can produce unintuitive curves; preview in the animation window to verify.
55+
56+
## Debugging & Utilities
57+
58+
```csharp
59+
// Convert quaternion to Euler for logging
60+
Vector3 display = transform.rotation.eulerAngles;
61+
Debug.Log($"Heading: {display.y:0}° Pitch: {display.x:0");
962

10-
// Using a Vector
11-
Vector3 EulerRotation = new Vector3(30, 10, 0);
12-
Quaternion rotation = Quaternion.Euler(EulerRotation);
63+
// Clamp pitch while keeping yaw free
64+
Vector3 clamped = transform.localEulerAngles;
65+
clamped.x = Mathf.Clamp(Mathf.DeltaAngle(0f, clamped.x), -45f, 45f);
66+
clamped.x = (clamped.x + 360f) % 360f; // convert back to 0-360 range
67+
transform.localEulerAngles = clamped;
1368

14-
// Convert a transform's Quaternion angles to Euler angles
15-
Quaternion quaternionAngles = transform.rotation;
16-
Vector3 eulerAngles = quaternionAngles.eulerAngles;
69+
// Build a quaternion after editing Euler values
70+
Vector3 offsetEuler = new Vector3(0f, 45f, 0f);
71+
Quaternion offsetRotation = Quaternion.Euler(offsetEuler) * transform.rotation;
1772
```
1873

74+
Use Euler angles where readability and simple axis locks matter, but switch to quaternions for compound rotations, interpolation, and physics-facing logic. Combining both viewpoints lets you keep authoring intuitive while the runtime math stays robust.

0 commit comments

Comments
 (0)