[Unity] SmoothDampを構造体化して使いやすくする

Posted on September 03, 2021  -  1 min read

Unityには、値を滑らかに変化させるMathf.SmoothDamp()メソッドが用意されている。

public static float SmoothDamp(
    float current,
    float target,
    ref float currentVelocity,
    float smoothTime,
    float maxSpeed = Mathf.Infinity,
    float deltaTime = Time.deltaTime
);

しかし、引数currentとcurrentVelocityを変数としてフィールド等に保持しておく必要があり、使いづらく感じるところがあった。

SmoothDampの構造体

SmoothDampで使うこれらの変数は構造体としてまとめると、コードの見通しが良くなる。

using UnityEngine;

public struct SmoothDampFloat
{
    private float _current;
    private float _currentVelocity;

    public float GetNext(float target, float smoothTime, float maxSpeed, float deltaTime) =>
        _current = Mathf.SmoothDamp(
            _current,
            target,
            ref _currentVelocity,
            smoothTime,
            maxSpeed,
            deltaTime
        );

    public float GetNext(float target, float smoothTime, float maxSpeed) =>
        _current = Mathf.SmoothDamp(
            _current,
            target,
            ref _currentVelocity,
            smoothTime,
            maxSpeed
        );

    public float GetNext(float target, float smoothTime) =>
        _current = Mathf.SmoothDamp(
            _current,
            target,
            ref _currentVelocity,
            smoothTime
        );
}

サンプル

実際の使い方は次の通り。

using UnityEngine;
using UnityEngine.Assertions;

internal class TestSmoothDamp : MonoBehaviour
{
    [SerializeField] private Transform _current;
    [SerializeField] private Transform _target;

    private SmoothDampFloat _smoothValue;

    private void Update()
    {
        Assert.IsNotNull(_current);
        Assert.IsNotNull(_target);

        var next = _smoothValue.GetNext(_target.localPosition.x, 0.1f);

        var currentPos = _current.localPosition;
        currentPos.x = next;
        _current.localPosition = currentPos;
    }
}

例では代表的なSmoothDampメソッドのみを示したが、他バリエーションのSmoothDampメソッドにも同様に対応できる。

  • Mathf.SmoothDampAngle()
  • Vector2.SmoothDamp()
  • Vector3.SmoothDamp()

結論

SmoothDampメソッドは、deltaTimeによって動きが変わってしまったり、速度が急激に変化したりする問題を解消して滑らかな値変化を実現できる便利メソッドである。

ただし、Damping処理を行うため、どうしても計算途中の値をどこかに保存しておく必要がある。

これらの状態変数とDamping処理はオブジェクトとして一元管理したほうが楽ができそう。

参考