Vector3Dには、ある地点からある地点へ移動する関数がいくつかあるため、比較しました。
Vector3DのAPIから、Lerp、Slerp、Smooth Damp、MoveTowardsを 以下のスクリプト で比較してみます。
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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; public class Move : MonoBehaviour { enum MoveFunc { Lerp, Slerp, SmoothDamp, MoveTowards, } private Transform _transform; private Vector3 _startPos; private Vector3 _targetPos; private float _startTime; private Vector3 _velocity = Vector3.zero; public float SmoothTime = 2f; public float Speed = 1f; public float JourneyLength = 10f; [SerializeField] private MoveFunc _moveFunc; void Start () { _transform = GetComponent<Transform>(); _startPos = _transform.position; _targetPos = _transform.TransformPoint(new Vector3(JourneyLength, 0, 0)); _startTime = Time.time; } void Update () { switch (_moveFunc) { case MoveFunc.Lerp: transform.position = Vector3.Lerp(_startPos, _targetPos, CalcMoveRatio()); break; case MoveFunc.Slerp: transform.position = Vector3.Slerp(_startPos, _targetPos, CalcMoveRatio()); break; case MoveFunc.SmoothDamp: transform.position = Vector3.SmoothDamp(_transform.position, _targetPos, ref _velocity, SmoothTime); break; case MoveFunc.MoveTowards: var step = Speed * Time.deltaTime; transform.position = Vector3.MoveTowards(_transform.position, _targetPos, step); break; default: throw new Exception(); } } float CalcMoveRatio() { var distCovered = (Time.time - _startTime) * Speed; return distCovered / JourneyLength; } } |
Lerpは線形補完なので真っすぐに、Slerpは球面線形補完のため円を描くように開始と終了の2地点が補完がされます。
SmoothDampは、最初と最後の速度がゆっくりになります。TPSのカメラの追従とかで使われます。第2引数は、現在の速度を表し、関数内部で更新されます。第3引数の値は、目標地点へ到達するおおよその時間を表します。
Lerp、Slerpの第一引数は開始地点であり、変化はしません。一方で、SmoothDamp、MoveTowardsの第一引数は、移動するオブジェクトの現在地を取ります。
LerpとMoveTowardsは、表示上の結果は同じですが、意味合いが異なります。Lerpは2地点間の距離に対して、第3引数で渡した割合に位置する座標を返します。 MoveTowards は、現在地点から目標地点へのベクトルに対して、第3引数で渡した値だけ移動した座標を返します。