3Dオブジェクトを回転させる時、X軸、Y軸、Z軸の角度で表現する方法(オイラー角)を使うことがあります。
しかし、オイラー角には重大な問題があることを知っていますか。
ジンバルロック(Gimbal Lock)という現象が起きると、回転の自由度が失われ、意図した通りの回転ができなくなるんです。
この記事では、オイラー角の問題点、特にジンバルロックについて、Unity実装例とともに解説します。
オイラー角とは何か(ゲーム制作目線)

オイラー角は、3D空間での回転を、X軸、Y軸、Z軸の3つの角度で表現する方法です。
Unityでは、TransformのeulerAnglesプロパティで、オイラー角を取得・設定できます。
オイラー角は、人間にとって直感的で理解しやすいという利点があります。
「X軸に30度、Y軸に45度回転させる」というように、角度で表現できるため、設定や調整が簡単です。
しかし、オイラー角には重大な問題があります。
それが、ジンバルロックという現象です。
オイラー角の表記方法
オイラー角は、通常、3つの軸の順番で回転を適用します。
Unityでは、Z→X→Yの順(ZXY順)で回転を適用します。
ただし、回転の順番が異なると、結果が変わることがあります。
これは、回転の順番が非可換(交換できない)ためです。
ジンバルロックとは何か

ジンバルロックとは、3つの回転軸のうち、2つの軸が同じ方向を向いてしまい、回転の自由度が失われる現象です。
具体的には、Y軸回転を90度(または-90度)にした時、X軸とZ軸が同じ方向を向いてしまい、2つの軸が1つの軸として機能してしまいます。
この状態になると、X軸とZ軸の回転が、同じ効果を生み出してしまうため、意図した通りの回転ができなくなります。
ジンバルロックが起きる条件
ジンバルロックは、中間の軸(UnityではX軸)が90度または-90度に近づいた時に発生します。
例えば、Y軸→X軸→Z軸の順で回転を適用する場合、X軸が90度になると、Y軸とZ軸が同じ方向を向いてしまいます。
この状態では、Y軸とZ軸の回転が同じ効果になるため、1つの自由度が失われます。
ジンバルロックの具体例
カメラの回転で例えると、上を向きすぎてX軸が90度に近づくと、左右の回転(Y軸)とロール(Z軸)が同じ方向に効いてしまいます。
FPSゲームで、カメラを上に向けすぎた時に、左右に回転させようとしても、カメラが不自然に動いてしまうのは、このジンバルロックが原因です。
作り方は分かった。
でも完成まで行けない人へ
当たり判定・移動・カメラ・AIまで、
実装しながら学べる「永久会員チケット」です。
※ まずは内容を見るだけでOK
ゲームでの具体的な問題

オイラー角の問題が、ゲームでどう影響するかを確認してみましょう。
FPSカメラの回転制限
FPSゲームで、カメラを上下に回転させる時、オイラー角を使うと、上を向きすぎた時にジンバルロックが発生します。
この問題を回避するために、上下回転を-90度〜90度に制限することが一般的です。
しかし、これでも完全には解決できません。
回転補間の問題
オイラー角を使って回転を補間すると、ジンバルロックが起きる可能性があります。
特に、回転角度が大きい場合、補間の途中でジンバルロックが発生することがあります。
これにより、滑らかな回転補間ができないことがあります。
回転の順番の問題
オイラー角では、回転の順番が重要です。
同じ角度でも、回転の順番が異なると、結果が変わります。
これにより、予期しない回転が起きることがあります。
数値計算の誤差
オイラー角を使うと、計算の過程で誤差が蓄積されることがあります。
特に、複数の回転を組み合わせる場合、誤差が大きくなることがあります。
- ジンバルロックが発生する(回転の自由度が失われる)
- 回転の順番によって結果が変わる
- 回転補間が滑らかにできない場合がある
- 数値計算の誤差が蓄積される
考え方・仕組みを図解イメージで説明

ジンバルロックの仕組みは、「回転軸の重なり」という考え方で理解できますね。
3軸の回転システム
オイラー角では、3つの軸(X軸、Y軸、Z軸)で回転を表現します。
それぞれの軸は、独立して回転させることができます。
しかし、特定の角度になると、2つの軸が同じ方向を向いてしまうことがあります。
ジンバルロックの発生条件
Unityでは、X軸、Y軸、Z軸の順で回転を適用します。
X軸が90度(または-90度)になると、Y軸とZ軸が同じ方向を向いてしまいます。
この状態では、Y軸とZ軸の回転が同じ効果になるため、1つの自由度が失われます。
ジンバルロックの回避方法
ジンバルロックを回避する方法には、主に2つあります。
1つ目は、回転角度を制限する方法です。
上下回転を-90度〜90度に制限すれば、ジンバルロックが起きる範囲を避けられます。
2つ目は、クォータニオンを使う方法です。
クォータニオンは、ジンバルロックが起きない表現方法です。
クォータニオンとの比較
クォータニオンは、オイラー角とは異なる回転の表現方法です。
クォータニオンは、4つの値(x, y, z, w)で回転を表現します。
クォータニオンを使うことで、ジンバルロックを完全に回避できます。
- ジンバルロックは、オイラー角の根本的な問題で、完全に回避することは難しい
- 回転角度を制限すれば、ジンバルロックの影響を減らせる
- クォータニオンを使うことで、ジンバルロックを完全に回避できる
- Unityでは、内部的にはクォータニオンで回転を管理している
Unityで実装する際の注意点(代表例)

Unityでオイラー角を使う場合の注意点と、対処方法を見ていきましょう。
回転角度の制限
オイラー角を使う場合、回転角度を制限すれば、ジンバルロックの影響を減らせます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
public class EulerAngleCamera : MonoBehaviour { public float mouseSensitivity = 2.0f; public float verticalRotationLimit = 80f; // 上下回転の制限 float verticalRotation = 0f; void Update() { // マウスの移動量を取得 float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity; float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity; // 上下回転(制限付き) verticalRotation -= mouseY; verticalRotation = Mathf.Clamp(verticalRotation, -verticalRotationLimit, verticalRotationLimit); // オイラー角で回転を適用 transform.localEulerAngles = new Vector3( verticalRotation, transform.localEulerAngles.y + mouseX, 0 ); } } |
このコードでは、上下回転を-80度〜80度に制限すれば、ジンバルロックが起きる範囲を避けています。
クォータニオンへの変換
オイラー角をクォータニオンに変換すれば、ジンバルロックを回避できます。
|
1 2 3 4 5 6 7 |
// オイラー角からクォータニオンに変換 Vector3 eulerAngles = new Vector3(30f, 45f, 0f); Quaternion rotation = Quaternion.Euler(eulerAngles); // クォータニオンを適用 transform.rotation = rotation; |
このコードでは、オイラー角をクォータニオンに変換してから適用しています。
ただし、オイラー角の時点で既にジンバルロックが起きている場合は、変換しても解決できません。
クォータニオンを直接使う方法
最初からクォータニオンを使うことで、ジンバルロックを完全に回避できます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
public class QuaternionCamera : MonoBehaviour { public float mouseSensitivity = 2.0f; public float verticalRotationLimit = 80f; float verticalRotation = 0f; float horizontalRotation = 0f; void Update() { // マウスの移動量を取得 float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity; float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity; // 回転角度を更新 verticalRotation -= mouseY; verticalRotation = Mathf.Clamp(verticalRotation, -verticalRotationLimit, verticalRotationLimit); horizontalRotation += mouseX; // クォータニオンで回転を適用 transform.rotation = Quaternion.Euler(verticalRotation, horizontalRotation, 0); } } |
このコードでは、クォータニオンを直接使うことで、ジンバルロックを回避しています。
回転補間での注意点
オイラー角を使って回転を補間する場合、ジンバルロックが起きる可能性があります。
|
1 2 3 4 5 6 7 8 9 10 11 12 |
// ❌ オイラー角で補間(問題が起きる可能性) Vector3 currentEuler = transform.eulerAngles; Vector3 targetEuler = target.eulerAngles; Vector3 lerpedEuler = Vector3.Lerp(currentEuler, targetEuler, t); transform.eulerAngles = lerpedEuler; // ✅ クォータニオンで補間(推奨) Quaternion currentRotation = transform.rotation; Quaternion targetRotation = target.rotation; Quaternion lerpedRotation = Quaternion.Slerp(currentRotation, targetRotation, t); transform.rotation = lerpedRotation; |
回転を補間する場合は、必ずクォータニオンを使うことをおすすめします。

まとめ

この記事では、オイラー角の問題点について見てきました。
重要なポイントをおさらいします。
- オイラー角は、ジンバルロックという重大な問題がある(回転の自由度が失われる)
- ジンバルロックは、中間の軸が90度(または-90度)に近づいた時に発生する
- オイラー角は、回転の順番によって結果が変わり、数値計算の誤差が蓄積される
- 回転角度を制限すれば、ジンバルロックの影響を減らせる
- クォータニオンを使うことで、ジンバルロックを完全に回避できる
オイラー角は、直感的で使いやすいという利点があります。
しかし、ジンバルロックという根本的な問題があるため、3D回転を扱う際は、できるだけクォータニオンを使うことをおすすめします。
Unityでは、内部的にはクォータニオンで回転を管理しているため、最初からクォータニオンを使う方が安全です。
回転補間や、複雑な回転処理を行う場合は、特にクォータニオンを使うことが重要です。
数学的な理論だけでなく、実際のゲーム実装とセットで学ぶことで、理解が深まるはずです。
Unity入門の森では、クォータニオンを含む回転処理を、実装しながら体系的に学べます。
ぜひチェックしてみてください。
Unity入門の森をチェック Unity初心者でも安心。動画解説+完成サンプル付きで実装まで進められます





コメント