【Unity】Slerpとは?球面線形補間で滑らかに移動・回転を行うメソッド

球面線形補間を行うSlerpとは? Unity

こんにちは、ともくんのゲーム作り部屋にようこそ!

このページでは、

「UnityのSlerpメソッドってなに?」

「Slerpを使うとどんなことができるの?」

というお悩みの方に向けた内容となっています。

Slerpとは、Spherical Linear Interpolateの英語の略で、球面線形補間と呼ばれる処理を行ってくれるメソッドです。

この球面線形補間とは、2つの値の間の数値を、球面を使って近似的に補うことを言います。

例えば、オブジェクトの回転処理やカメラを回転させたりする際に、Slerpメソッドを使うことで、滑らかに回転処理を行うことができます。

そこで、このページでは、Unityで使えるSlerpメソッドについて、どんなメソッドなのか、また使い方までをまとめていきます。

この記事を書いた人

ゲーム作りを学び始めた一児のパパです。
このブログは、子供から「ゲームを作ってみたい!」と言われ、非プログラマーでゲーム作りをしたことない僕が、ゲーム作りの本を読んで独学でゲーム開発を学んでいるブログです。
同じように初めてゲーム作りをしている方と一緒に学んでいけるようなブログに出来たらいいなと思っています。
また、「このコードはおかしい」とか「もっと良い書き方があるよ!」などあれば、どんどん指摘して頂けると助かります。

Slerpとは?球面線形補間を使って滑らかな処理を作れるメソッド

まずは、Slerpメソッドがどういうメソッドなのかを紹介していきます。

Slerpメソッドは、球面線形補間という処理を行うメソッドで、Vector3Quaternionの構造体で定義されています。

この球面線形補間というのは、2つの間の値を球面を使って近似的に求めて補うことを指しています。

例えば、それぞれ異なる座標のAとBがあった際に、このAとBを繋ぐ球面の線があると想定します。

そして、この球面に沿ったAとBの間の指定した位置の座標を求めて補うことを球面線形補間と呼びます。

球面線形補間で取得した値を使うことで、その球面線上に沿ってオブジェクトなどを移動させることができるようになります。

なお、Slerpメソッドと同じように、2つの間の補間を行う処理としてLerpメソッドというものがあります。

このLerpメソッドは、線形補間の処理を行うメソッドで、Slerpが球面だったのに対して、Lerpは2つの間を直線を使って値を求める処理を行います。

Slerpの使い方

ここからは、Slerpメソッドの使い方について紹介していきます。

引数で2つの値と補間する位置を設定する

Slerpメソッドを使う際は、引数で2つの値補間する位置を指定していきます。

例えば、Vector3型でSlerpを使う際は、以下のように記述していきます。

Vector3.Slerp(a, b, t);

a:始点となるVector3型の値
b:終点となるVector3型の値
t:球面の線上で補間する位置(0から1までのfloat型)

tの補間する位置は、aを0、bを1とした際の球面線上での割合(位置)のことを指しています。

つまり、球面の線上における引数tで指定した位置であるVector3型の値が、Slerpメソッドによって返されることになります。

なお、Quaternion型で使用する際は、aとbをQuaternion型の値にして設定していきます。

Slerpを使った実例

ここからは、実際にSlerpメソッドを使った実例を紹介していきます。

オブジェクトを円弧上で移動させる処理

オブジェクトの移動処理にSlerpメソッドを使うことで、球面に沿って移動する動きを行うことができます。

ここでは、以下のように球体のオブジェクトを配置して、空オブジェクトで目標となる座標を指定しておきます。

そして、球体のオブジェクトに以下のスクリプトをアタッチしておきます。

using UnityEngine;

public class Test : MonoBehaviour
{
    public GameObject target;   // 空オブジェクトを取得
    Vector3 startPosition;  // スタート地点を取得

    void Start()
    {
        startPosition = transform.position; // 最初にオブジェクトがいた場所を取得
    }

    void Update()
    {
        transform.position = Vector3.Slerp(startPosition, target.transform.position, Time.time / 3); // 線形補間した値を代入して移動させる処理
    }
}

15行目で、Vector3.Slerpメソッドを使って、補間されたベクトル値を自身の座標に代入する処理を行っています。

また、補間位置には、ゲーム時間を計測する「Time.time」を3で割る処理を行っていて、3秒で目標となる座標に到達する処理を記述しています。

実際にゲームを実行してみると、

目標となる座標まで、弧を描きながら3秒間で到達しているのが分かります。

他にも、メニューなどUIオブジェクトを動かしたりする演出にも、Slerpメソッドは使えそうです。

カメラの回転を行う処理

オブジェクトなどの回転処理に、Slerpメソッドはよく使われています。

ここでは、キー操作でカメラオブジェクトを回転させる処理を作ってみます。

カメラオブジェクトに、以下のスクリプトをアタッチしておきます。

using UnityEngine;

public class Test2 : MonoBehaviour
{
    int direction = 0;  // 回転させる向き
    bool isRotation = false;    // 回転中かどうかを判定する
    Quaternion startQuaternion; // 回転開始時のQuaternionを取得

    void Update()
    {
        // キーを押した場合
        if (Input.GetKeyDown(KeyCode.D) || Input.GetKeyDown(KeyCode.A) && !isRotation)
        {
            isRotation = true;  // 回転中に変更する
            startQuaternion = transform.rotation;   // 押した際の回転を保持する

            // Dキーを押した場合
            if (Input.GetKeyDown(KeyCode.D))
            {
                direction = 1;
            }
            // Aキーを押した場合
            else if (Input.GetKeyDown(KeyCode.A))
            {
                direction = -1;
            }
        }

        // 回転を行う場合
        if (isRotation)
        {
            Quaternion rotationQuaternion = Quaternion.AngleAxis(90.0f * direction, Vector3.up);    // 90度に左右に回転させるQuaternion
            transform.rotation = Quaternion.Slerp(transform.rotation, startQuaternion * rotationQuaternion, Time.deltaTime * 3);    // 補間した値を自身の回転にセットする
            
            // 回転が終了した場合
            if (transform.rotation == startQuaternion * rotationQuaternion)
            {
                isRotation = false; // 回転をしない判定に変更
            }
        }
    }
}

DキーもしくはAキーを押した時のオブジェクトの回転を、15行目でstartQuaternionの変数で取得しています。

回転処理を行い始めた際の33行目で、Quaternion.Slerpメソッドを使って、補間した値をrotationに代入する処理を行っています。

始点はキーを押した際のQuaternion、終点はAngleAxisで作成した90度左右に回転するQuaternionを合成した値を指定しています。

これでゲームを実行してみると、

キーを押すと、カメラが左右に90度回転する処理が行われているのが分かります。

まとめ

このページでは、Unityで使えるSlerpメソッドについて、どんなメソッドなのか、また使い方までをまとめていきましたが、いかがでしたでしょうか?

Slerpは、球面線形補間を行うメソッドで、2つの間を球面に沿って滑らかに変化させる処理を行います。

Slerpメソッドは、特にQuaternion型を使って、オブジェクトやカメラの回転処理を作る際に使われることが多いです。

他にも、UIオブジェクトの動きなどで、球面に沿って動かすという演出をSlerpメソッドで作ることもできます。

最後までお読みいただきまして、ありがとうございました!

コメント