🍁 値を特定の範囲に収める拡張メソッド

2023-01-22 /Development #Unity

お仕事でメタバースのワールドみたいなのを作っていて、ステージの障害物的なオブジェクトをゆらゆらさせるスクリプトを書いていたんだけど、Sinの値を特定の範囲に変換する処理を毎回書くのが面倒なのでメモ。

Remap関数

Sinの値は-1から1までの間で返ってきますが、Unityの上では大抵は「ここでは上下に50m往復させる」「ここでは-180度から180度までの間の角度を往復させる」みたいな感じでなんらかの幅に調整して使う事になります。

-1から1までの間を、例えば0から50の値に変換しようと思ったら、from/toとmin/maxをゴニョゴニョ計算したら良いだけでそう難しい計算ではないのですが、拡張メソッドを書いておくと楽なのでこんな感じで書いています(ついでに Mathf.Clamp で想定外の値が入ってきた時にカットする処理も入れています)。

コピーしました
public static float Remap(this float value, float fromMin, float fromMax, float toMin, float toMax, bool clamp = true)
{
    var val = (value - fromMin) / (fromMax - fromMin) * (toMax - toMin) + toMin;
    return clamp ? Mathf.Clamp(val, toMin, toMax) : val;
}

こうしておくと以下みたいな感じで値を調整する事が可能になります。

コピーしました
元の値.Remap(-1, 1, 変換後の最小値, 変換後の最大値);

Flash全盛の時代にはよくお世話になったものです…

Sin/Cosで使用する場合

入ってくる値が-1〜1になる場合は結構多いので、以下みたいなメソッドも追加しておくと楽です。

コピーしました
public static float RemapSin(this float value, float toMin, float toMax)
{
    return Remap(value, -1, 1, toMin, toMax);
}

こうしておくと以下みたいな感じで扱う事が可能になります。

コピーしました
元の値.RemapSin(変換後の最小値, 変換後の最大値);

拡張メソッドまとめ

また使う事があるかもしれないのでまとめておきました。これで次回はササっと実装できるハズ…

コピーしました
using UnityEngine;

public static class FloatExtensions
{
    /// <summary>
    /// 渡されたfromの範囲内の値をtoの範囲内での値に変更する
    /// </summary>
    /*
    howto:
    value.Remap(-1, 1, 0, 100);
     */
    public static float Remap(this float value, float fromMin, float fromMax, float toMin, float toMax, bool clamp = true)
    {
        var val = (value - fromMin) / (fromMax - fromMin) * (toMax - toMin) + toMin;
        return clamp ? Mathf.Clamp(val, toMin, toMax) : val;
    }

    /// <summary>
    /// 渡された-1〜1の値をtoの範囲内での値に変更する
    /// </summary>
    /*
    howto:
    value.RemapSin(0, 100);
     */
    public static float RemapSin(this float value, float toMin, float toMax)
    {
        return Remap(value, -1, 1, toMin, toMax);
    }
}
Comment
comments powered by Disqus
Profile

石原 悠 / Yu Ishihara

デザインとプログラミングと編み物とヨーグルトが好きです。