Slerpで滑らかな回転補間を実装したいけど、計算式がどうなっているのか分からない。
UnityのQuaternion.Slerpを使うだけでいいのか、それとも計算式を理解する必要があるのか。
そんな疑問を抱えていませんか。
Slerpの計算式は、球面上を等速で移動するための三角関数を使った補間です。
この記事では、Slerpの計算式の仕組みと、Unityでの実装方法を見ていきましょう。
Slerpの計算式とは何か(ゲーム制作目線)

Slerpの計算式は、クォータニオンを球面上で等速補間する数式です。
基本となる計算式は、以下のようになります。
Slerp(q₁, q₂, t) = (sin((1-t)θ) / sin(θ)) × q₁ + (sin(tθ) / sin(θ)) × q₂
ここで、q₁は開始のクォータニオン、q₂は終了のクォータニオン、tは補間係数(0.0〜1.0)、θは2つのクォータニオン間の角度です。
この式のポイントは、sin関数を使うことで、球面上を等速で移動できることです。
Lerpでは直線的に補間するため、球面上を移動する距離が一定になりません。
しかし、Slerpでは、球面上を移動する角度(距離)が一定になるため、回転速度が一定になります。
Unityでは、Quaternion.Slerp関数が用意されており、この計算を自動で行ってくれます。
ただし、計算式を理解しておくと、より効果的な実装が可能です。
ゲームでの具体的な使い道

Slerpの計算式が、ゲームでどう活用されているかを確認してみましょう。
キャラクターの回転補間
プレイヤーキャラクターが、現在の向きから目標の向きへ滑らかに回転する際、Slerpの計算式が使われます。
例えば、TPSゲームで、キャラクターがカメラの方向を向く時です。
マウスを大きく動かすと、180度近く回転することがあります。
この時、Slerpの計算式を使えば、回転速度が一定になり、自然な動きになります。
カメラの視点切り替え
カメラが特定の方向へ回転する時も、Slerpの計算式が有効です。
ボス戦の開始時や、イベントシーンでカメラが視点を切り替える場面です。
Slerpの計算式を使うことで、一定速度で滑らかに回転します。
オブジェクトの回転アニメーション
ドアや宝箱が開く時の回転アニメーションでも、Slerpの計算式が使われます。
開き始めから閉じ終わりまで、一定の速度で回転するため、見た目が自然です。
特に、回転角度が大きい(90度以上)場合、Slerpの効果が顕著に現れます。
武器の向き調整
FPSゲームで、武器が敵を向く時にも、Slerpの計算式が役立ちます。
武器の向きを、プレイヤーの視線方向に滑らかに合わせる際、一定速度で回転します。
Lerpを使うと、武器の動きが不規則になることがありますが、Slerpなら一定速度を保てます。
- 回転角度が大きい場合(90度以上)
- 回転速度を一定に保ちたい場合
- カメラの回転補間
- キャラクターや武器の向き変更
- 滑らかな回転アニメーション
作り方は分かった。
でも完成まで行けない人へ
当たり判定・移動・カメラ・AIまで、
実装しながら学べる「永久会員チケット」です。
※ まずは内容を見るだけでOK
考え方・仕組みを図解イメージで説明

Slerpの計算式は、「球面上の最短経路で等速移動」という考え方で理解できますね。
角度θの計算
まず、2つのクォータニオンq₁とq₂の間の角度θを計算します。
角度θは、2つのクォータニオンの内積から求められます。
cos(θ) = q₁ · q₂
この式から、θ(シータ)を求めるには、arccos関数を使います。
θ = arccos(q₁ · q₂)
ただし、クォータニオンの内積が負の場合は、短い経路を選ぶために、q₂の符号を反転させる必要があります。
Slerpの計算式の導出
角度θが分かると、球面上を等速で移動する補間が可能です。
Slerpの計算式は、以下のように導出されます。
球面上を移動する距離は、角度θに比例します。
補間係数tが0から1まで変化する時、移動する角度は0からθまで変化します。
この時、sin関数を使うことで、等速で移動できますね。
Slerp(q₁, q₂, t) = (sin((1-t)θ) / sin(θ)) × q₁ + (sin(tθ) / sin(θ)) × q₂
この式で、t = 0の時はq₁、t = 1の時はq₂になります。
回転速度が一定になる理由
Lerpは、直線的に補間するため、球面上を移動する距離が一定ではありません。
具体的には、球面上を移動する角度が、tの値に応じて変化します。
一方、Slerpでは、移動する角度がtに比例するため、回転速度が一定になります。
具体例で説明しましょう。
0度から180度まで回転する時、Lerpを使うと、各ステップで移動する角度が異なります。
一方、Slerpを使うと、各ステップで移動する角度が一定になるため、回転速度が一定になります。
- Slerpの計算式は、sin関数を使うため、計算コストが高い
- 角度θが0に近い場合、sin(θ)が0に近づくため、数値計算の誤差に注意が必要
- 回転角度が小さい(30度以下)場合は、Lerpでも十分な場合が多い
UnityでSlerpの計算式を実装する方法

UnityでSlerpの計算式を実装する方法を、具体的なコード例とともに説明します。
Quaternion.Slerpの基本的な使い方
Unityでは、Quaternion.Slerp関数が用意されています。
この関数を使えば、Slerpの計算式を自動で実行してくれます。
|
1 2 3 4 5 6 7 8 |
// 現在の回転と目標の回転 Quaternion currentRotation = transform.rotation; Quaternion targetRotation = Quaternion.LookRotation(targetPosition - transform.position); // Slerpで補間(tは0から1の値) float t = Time.deltaTime * rotationSpeed; transform.rotation = Quaternion.Slerp(currentRotation, targetRotation, t); |
このコードでは、現在の回転から目標の回転まで、一定速度で補間します。
rotationSpeedは、回転の速さを制御するパラメータです。
手動でSlerpの計算式を実装する場合
Unityの関数を使わず、手動でSlerpの計算式を実装する場合のコード例です。
|
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 27 28 29 30 31 32 |
Quaternion ManualSlerp(Quaternion a, Quaternion b, float t) { // 短い経路を選ぶ float dot = Quaternion.Dot(a, b); if (dot < 0f) { b = new Quaternion(-b.x, -b.y, -b.z, -b.w); dot = -dot; } // 角度θを計算 float theta = Mathf.Acos(Mathf.Clamp(dot, -1f, 1f)); // sin(θ)が0に近い場合、Lerpにフォールバック float sinTheta = Mathf.Sin(theta); if (sinTheta < 0.0001f) { return Quaternion.Lerp(a, b, t); } // Slerpの計算式 float w1 = Mathf.Sin((1f - t) * theta) / sinTheta; float w2 = Mathf.Sin(t * theta) / sinTheta; return new Quaternion( w1 * a.x + w2 * b.x, w1 * a.y + w2 * b.y, w1 * a.z + w2 * b.z, w1 * a.w + w2 * b.w ).normalized; } |
このコードでは、Slerpの計算式を手動で実装しています。
ただし、実際の開発では、UnityのQuaternion.Slerpを使う方が確実で効率的です。
キャラクターの向き変更の実装例
キャラクターがマウスの方向を向く例を見てみましょう。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
void Update() { // マウスの位置を取得 Vector3 mousePosition = Input.mousePosition; mousePosition.z = 10f; // マウス位置をワールド座標に変換 Vector3 worldPosition = Camera.main.ScreenToWorldPoint(mousePosition); // キャラクターからマウス位置への方向 Vector3 direction = (worldPosition - transform.position).normalized; // 目標の回転 Quaternion targetRotation = Quaternion.LookRotation(direction); // Slerpで滑らかに回転 float rotationSpeed = 5f; transform.rotation = Quaternion.Slerp( transform.rotation, targetRotation, Time.deltaTime * rotationSpeed ); } |
このコードでは、キャラクターがマウスの位置を向くように、滑らかに回転します。
Slerpの計算式により、回転速度が一定になります。
数値計算の誤差への対応
Slerpの計算式では、sin(θ)が0に近い場合、数値計算の誤差が大きくなります。
この場合、UnityのQuaternion.Slerpは自動的にLerpにフォールバックします。
手動で実装する場合も、同様の対応が必要です。
パフォーマンスへの配慮
Slerpの計算式は、sin関数やarccos関数を使うため、計算コストが高いです。
毎フレーム、多数のオブジェクトでSlerpを使うと、パフォーマンスに影響が出る可能性があります。
対策として、回転角度が小さい場合はLerpを使い、大きい場合のみSlerpを使うという方法があります。

まとめ

この記事では、Slerpの計算式について見てきました。
重要なポイントをおさらいします。
- Slerpの計算式は「sin関数を使った球面上の等速補間」で、回転速度が一定になる
- 計算式は「(sin((1-t)θ) / sin(θ)) × q₁ + (sin(tθ) / sin(θ)) × q₂」で表される
- 角度θは、2つのクォータニオンの内積からarccos関数で求められる
- UnityではQuaternion.Slerp関数が用意されており、自動で計算してくれる
- Slerpは計算コストが高いため、必要に応じてLerpと使い分けることが重要
Slerpの計算式は、3Dゲームで滑らかな回転を実現するために、重要な技術です。
計算式を完全に理解していなくても、UnityのQuaternion.Slerpを使えば実装できます。
しかし、計算式を理解しておくと、より効果的な実装や、パフォーマンスの最適化が可能です。
まずは、Quaternion.Slerpを使って、実際の動作を確認してみましょう。
実際に試してみることで、Slerpの効果を実感できるはずです。
数学的な理論だけでなく、実際のゲーム実装とセットで学ぶことで、理解が深まるはずです。
Unity入門の森では、クォータニオンを含む回転処理を、実装しながら体系的に学べます。
ぜひチェックしてみてください。
Unity入門の森をチェック Unity初心者でも安心。動画解説+完成サンプル付きで実装まで進められます





コメント