【Unity】LerpとSlerpで実現する滑らかな移動と回転の極意

作成: 2025-12-10

Unityでオブジェクトを滑らかに動かしたり回転させたりするために必須の関数、Lerp(線形補間)とSlerp(球面線形補間)の使い方を、初心者でも理解できるように解説します。実践的なC#コード例付きで、あなたのゲーム表現をワンランクアップさせましょう。

概要

Unityでゲーム開発を始めたばかりのとき、オブジェクトの移動や回転を実装する際に、transform.position = targetPosition; のように直接座標を代入していませんか?

この方法では、オブジェクトは一瞬で目標地点にワープしてしまい、「カクカク」とした不自然な動きになってしまいます。特にプレイヤーキャラクターやカメラの動きが不自然だと、ゲームの品質は大きく損なわれてしまいます。

私たちが目指すのは、まるでプロのゲームのような 「滑らかで心地よい」 アニメーションです。この滑らかな動きを実現するために、Unity開発者が必ずと言っていいほど利用するのが、 Lerp (ラープ)と Slerp (スラープ)という二つの強力な関数です。

この記事では、この二つの補間(ほかん)関数、Lerp(線形補間)Slerp(球面線形補間) の基本的な概念から、実際のUnityプロジェクトでコピペしてすぐに使える実践的なC#コードまでを、初心者の方にも分かりやすく丁寧に解説します。

Lerp(線形補間)とは?

Lerpは「Linear Interpolation(線形補間)」の略です。これは、二つの値(AとB)の間を、指定した割合(t)で直線的に補間する(埋める)計算手法です。

Unityでは、Vector3.LerpColor.LerpMathf.Lerpなど、様々な型に対してこの関数が用意されています。

関数の基本形:

// A: 開始値, B: 終了値, t: 補間係数 (0.0fから1.0f)
結果 = Lerp(A, B, t);
  • t = 0.0f のとき、結果は A になります。
  • t = 1.0f のとき、結果は B になります。
  • t = 0.5f のとき、結果は AB のちょうど中間になります。

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について深く掘り下げました。

最後に、この記事で学んだ重要なポイントをまとめます。

  1. Lerp(線形補間) は、位置や色など、直線的な変化が必要な場面で使われます。
  2. Lerp(A, B, t)tspeed * Time.deltaTime を使うと、目標に近づくにつれて速度が落ちるイージングアウト効果が得られます。
  3. Slerp(球面線形補間) は、主にQuaternion(回転) を扱う際に使われ、球面上の最短経路を一定の角速度で滑らかに補間します。
  4. カクカクした動きを避けるためには、直接代入ではなく、Update関数内でLerpやSlerpを使って毎フレーム少しずつ目標に近づける処理が必要です。
  5. 回転を扱う際は、不自然な動きを防ぐためにLerpではなくSlerpを使うのがプロの常識です。

これらの知識とコード例を活用して、あなたのUnityプロジェクトにプロフェッショナルな「滑らかさ」を取り入れてみてください。