概要
Unityでゲーム開発を始めたばかりのとき、オブジェクトの移動や回転を実装する際に、transform.position = targetPosition; のように直接座標を代入していませんか?
この方法では、オブジェクトは一瞬で目標地点にワープしてしまい、「カクカク」とした不自然な動きになってしまいます。特にプレイヤーキャラクターやカメラの動きが不自然だと、ゲームの品質は大きく損なわれてしまいます。
私たちが目指すのは、まるでプロのゲームのような 「滑らかで心地よい」 アニメーションです。この滑らかな動きを実現するために、Unity開発者が必ずと言っていいほど利用するのが、 Lerp (ラープ)と Slerp (スラープ)という二つの強力な関数です。
この記事では、この二つの補間(ほかん)関数、Lerp(線形補間) と Slerp(球面線形補間) の基本的な概念から、実際のUnityプロジェクトでコピペしてすぐに使える実践的なC#コードまでを、初心者の方にも分かりやすく丁寧に解説します。
Lerp(線形補間)とは?
Lerpは「Linear Interpolation(線形補間)」の略です。これは、二つの値(AとB)の間を、指定した割合(t)で直線的に補間する(埋める)計算手法です。
Unityでは、Vector3.Lerp、Color.Lerp、Mathf.Lerpなど、様々な型に対してこの関数が用意されています。
関数の基本形:
// A: 開始値, B: 終了値, t: 補間係数 (0.0fから1.0f)
結果 = Lerp(A, B, t);
t = 0.0fのとき、結果はAになります。t = 1.0fのとき、結果はBになります。t = 0.5fのとき、結果はAとBのちょうど中間になります。
Lerpは、オブジェクトの移動や色の変化、数値の滑らかな変化など、直線的な変化が必要な場面で最もよく使われます。
Slerp(球面線形補間)とは?
Slerpは「Spherical Linear Interpolation(球面線形補間)」の略です。Lerpが直線的な補間を行うのに対し、Slerpは球面上の最短経路に沿って補間を行います。
Slerpは主にQuaternion(クォータニオン)、つまりオブジェクトの回転を扱う際に使用されます。
なぜ回転にSlerpが必要なのか?
回転をLerpで補間しようとすると、回転の途中で速度が不均一になったり、最短経路を通らずに不自然な動きになったりする場合があります。Slerpを使うことで、常に一定の角速度で、最も自然で滑らかな回転を実現できます。
LerpとSlerpの決定的な違い
| 特徴 | Lerp (線形補間) | Slerp (球面線形補間) |
|---|---|---|
| 補間方法 | 直線的 | 球面上の最短経路に沿って |
| 主な用途 | Vector3 (位置), Color (色), float (数値) | Quaternion (回転) |
| 速度 | 目標に近づくにつれて減速する(イージングアウト) | 常に一定の速度(角速度) |
| 計算負荷 | 軽い | Lerpよりは重い(回転計算のため) |
初心者が躓きやすいポイント:LerpをUpdate関数で使う際の注意点
Vector3.Lerp(transform.position, targetPosition, speed) のように、補間係数 t に固定値(例: 0.1f)を使うと、目標地点に近づくにつれて移動速度が遅くなるイージングアウトという効 果が生まれます。
これは意図したアニメーションであれば問題ありませんが、「一定の速度で移動させたい」場合は、補間係数に Time.deltaTime を使った別の計算が必要になります。
実践例
例1:Lerpを使った滑らかな移動(イージングアウト)
このコードは、オブジェクトを目標地点に向かって滑らかに移動させます。目標に近づくにつれて速度が落ちる、自然な減速アニメーション(イージングアウト)を簡単に実現できます。
// ファイル名: LerpMovement.cs
using UnityEngine;
public class LerpMovement : MonoBehaviour
{
// 移動開始点と終了点
public Vector3 startPosition = new Vector3(-5f, 1f, 0f);
public Vector3 endPosition = new Vector3(5f, 1f, 0f);
// 移動速度(Lerpの補間係数として使用)
[Range(0.01f, 1f)]
public float speed = 0.1f;
void Start()
{
// 初期位置を設定
transform.position = startPosition;
}
void Update()
{
// 現在の位置から目標位置へ、speedの割合だけ近づける
// Time.deltaTimeを乗算することで、フレームレートに依存しない滑らかな移動を実現
// ただし、この実装では目標に近づくにつれて速度が落ちる(イージングアウト)
transform.position = Vector3.Lerp(transform.position, endPosition, speed * Time.deltaTime);
// 目標に十分に近づいたら、位置をリセットしてループさせる
if (Vector3.Distance(transform.position, endPosition) < 0.01f)
{
// 終了点と開始点を入れ替える
Vector3 temp = startPosition;
startPosition = endPosition;
endPosition = temp;
}
}
}
このスクリプトを任意のGameObjectにアタッチし、Inspectorで speed の値を調整してみてください。値が小さいほどゆっくりと、大きいほど速く目標に近づきます。
例2:Slerpを使った滑らかな回転
このコードは、オブジェクトを目標の角度に向かって滑らかに回転させます。Slerpを使うことで、回転の途中で速度が変化することなく、常に一定の角速度で優雅に回転します。
// ファイル名: SlerpRotation.cs
using UnityEngine;
public class SlerpRotation : MonoBehaviour
{
// 目標の回転角度(オイラー角)
public Vector3 targetEulerAngles = new Vector3(0f, 180f, 0f);
private Quaternion targetRotation;
// 回転速度(Slerpの補間係数として使用)
[Range(0.01f, 1f)]
public float rotationSpeed = 0.1f;
void Start()
{
// 目標のオイラー角をQuaternionに変換
targetRotation = Quaternion.Euler(targetEulerAngles);
}
void Update()
{
// 現在の回転から目標の回転へ、rotationSpeedの割合だけ近づける
// Slerpは球面線形補間を行い、常に一定の角速度で回転するため、回転アニメーションに最適
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);
// 目標に十分に近づいたら、目標回転を反転させてループさせる
if (Quaternion.Angle(transform.rotation, targetRotation) < 0.1f)
{
// 目標角度を反転
targetEulerAngles *= -1;
targetRotation = Quaternion.Euler(targetEulerAngles);
}
}
}
よくある間違い:Quaternionの直接操作
Unityの回転は、内部的にQuaternion(クォータニオン) という数学的な構造で管理されています。これはオイラー角(X, Y, Zの角度)よりも複雑ですが、ジンバルロック(特定の軸の回転が失われる現象)を防ぐために重要です。
回転を扱う際は、transform.rotation のようにQuaternionを直接操作するか、Quaternion.Euler() を使ってオイラー角からQuaternionに変換してからSlerpを使うようにしましょう。
まとめ
本記事では、Unityで滑らかな動きを実現するための二大巨頭、LerpとSlerpについて深く掘り下げました。
最後に、この記事で学んだ重要なポイントをまとめます。
- Lerp(線形補間) は、位置や色など、直線的な変化が必要な場面で使われます。
Lerp(A, B, t)のtにspeed * Time.deltaTimeを使うと、目標に近づくにつれて速度が落ちるイージングアウト効果が得られます。- Slerp(球面線形補間) は、主にQuaternion(回転) を扱う際に使われ、球面上の最短経路を一定の角速度で滑らかに補間します。
- カクカクした動きを避けるためには、直接代入ではなく、
Update関数内でLerpやSlerpを使って毎フレーム少しずつ目標に近づける処理が必要です。 - 回転を扱う際は、不自然な動きを防ぐためにLerpではなくSlerpを使うのがプロの常識です。
これらの知識とコード例を活用して、あなたのUnityプロジェクトにプロフェッショナルな「滑らかさ」を取り入れてみてください。