LoginSignup
9
7

More than 3 years have passed since last update.

【Unity(C#)】Lerp、Slerpを使った減速表現

Last updated at Posted at 2020-03-11

デモ

早速ですが、デモです。

ExMove.gif

OculusQuestのプレイエリア設定画面などもゆっくりとUIがプレイヤーの視線に追従するようになってます。

コード


using UnityEngine;

/// <summary>
/// 視線に追従させたいオブジェクトにアタッチ
/// </summary>
public class FollowEyeDirection : MonoBehaviour
{
    [SerializeField, Range(0.1f, 1.0f)] private float _positionLerpSpeed = 0.1f;
    [SerializeField, Range(0.1f, 1.0f)] private float _rotationLerpSpeed = 0.1f;
    [SerializeField] private float _distanceForwards = 5f;
    [SerializeField] private float _distanceUpwards = 1f;

    private void Update()
    {
        //正面に移動
        float posSpeed = _positionLerpSpeed;
        Vector3 posTo = Camera.main.transform.position + (Camera.main.transform.forward * _distanceForwards) + (Camera.main.transform.up * _distanceUpwards);
        transform.position = Vector3.Slerp(transform.position, posTo, posSpeed);

        //正面方向に回転
        float rotSpeed = _rotationLerpSpeed;
        Quaternion rotTo = Quaternion.LookRotation(transform.position - Camera.main.transform.position);
        transform.rotation = Quaternion.Slerp(transform.rotation, rotTo, rotSpeed);
    }
}

Lerp,Slerp

以前書いた記事でも取り上げたんですが、
Update内での挙動がいまいちよくわかってなかったのでもっかいまとめます。
【参考リンク】:Mathf.Lerp

まずはそれぞれの動き方について簡単に流して見ていきます。


Lerp

左右にカメラを振ると、直線的に追従してきます。

LerpMove.gif


Slerp

左右にカメラを振ると、曲線を描きながら(分かりづらいですが)追従してきます。

SLerpMove.gif

Lerpの使い方

Slerpも挙動が違うだけで使い方は一緒なのでLerpについてのみ書きます。

Vector3.Lerp(a, b, t)
のように使い、tabの間を補間します。

それぞれの引数の説明は下記です。
 a : 始点となるベクトル位置(型:Vector3)
 b : 終点となるベクトル位置(型:Vector3)
 t : 両端の距離を1とした時の割合(型:float, 0~1の範囲のみ)

【参考リンク】:[Unity] Vector3.Lerpの使い方

Update内で起きている処理のイメージ

  private void Update()
  {
    transform.position = Vector3.Lerp(transform.position, 目的地点, 移動の割合);
  }

今回の追従で利用した上記のコードを図解します。
※移動の割合は今回は0.2として話を進めます
a.PNG

結論を先に言うと、
第一引数である開始地点に移動させたいオブジェクトの座標を入れておくと
イイ感じにフワーって動いてくれる
って感じです(語彙力)。

上記では説明としてザックリ過ぎるので、もう少し細かく考えていきます。

Lerp関数の第三引数で指定した割合を使って、
開始地点から見た、目的地点までの20%の位置を算出します。

つまり、1フレーム目で実際に20%分、目的地まで進みます。

2フレーム目も同様に進みますが、先ほどの開始地点とは異なり、
すでに20%移動した先が開始地点となります。

つまり、2フレーム目では、
その時点での開始地点から目的地点までの20%分またさらに進むということです。

この20%分の移動を目的地点に到達するまで繰り返す、、、
というイメージです。

ポイントとしては
1フレーム分の移動の変化量がだんだん小さくなり、緩やかな曲線を描く
ということです。

この変化量の減衰のおかげでイイ感じにフワーってなります。

図解では少しわかりづらいですが、
20%のまたさらに20%、そのまたさらに20%、、、
というのを繰り返すことで、変化量がだんだんと小さくなります。

a.PNG

参考リンク

下記プロジェクト内のコードを使用させていただいてます。
【GitHub】:MagicLeapHandTracking

9
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
7