FC2ブログ
ヽ|∵|ゝ(Fantom) の 開発blog? ホーム »2020年12月
2020年12月の記事一覧

【Unity】【C#】範囲を指定できる Mathf.Repeat  


 今回は数学的な関数のちょっとした便利拡張メソッド。

 Unity においては、特に角度の計算に Mathf.Repeat() はよく使う。例えば入力された値(角度)を -180~180 度に収めたいなどの時だ。
 しかし、標準の Mathf.Repeat() では引数が元の値(t)と長さ(length)[=最大(を含まない)] なので、0~max(を含まない) の計算となる。なので、0~360(359) 度などには良いが、0 以外の開始値だと少し不便だったりする。

 そこで、Mathf.Repeat() に少し手を加えて、-180~180(を含まない) または -180~180(を含む) のような、範囲内を返せる2つの拡張メソッドを作っておこう。

 ちなみに Mathf クラスは C# 標準の Math クラスの軽量版で、C# 標準が double の計算に対して、Unity では float で計算するものと考えて良い。要するに精度より速度を優先したものである。なので、高い計算精度が欲しいときは Math クラスを使った方が良いだろう(当然処理速度は重くなるので注意)。


(※) Unity 2019.4 / Windows10(x64) で確認 (※バージョン依存はないと思う)



●下限~上限(を含まない)範囲を返す Mathf.Repeat
using UnityEngine;

public static class MathfExtentions //※クラス名は任意
{
/// <summary>
/// 下限~上限(を含まない)範囲を返す Mathf.Repeat
/// 2020/12/20 Fantom
/// http://fantom1x.blog130.fc2.com/blog-entry-390.html
/// </summary>
/// <param name="value">元の値</param>
/// <param name="min">下限 (inclusive)</param>
/// <param name="max">上限 (exclusive)</param>
/// <returns>min(inclusive)~max(exclusive) の Mathf.Repeat</returns>
public static float Repeat(this float value, float min, float max)
{
return Mathf.Repeat(value - min, max - min) + min;
}

//int 版
public static int Repeat(this int value, int min, int max)
{
return (int)Mathf.Repeat(value - min, max - min) + min;
}
}

●メインコード例
using UnityEngine;
using System.Text;

var sb = new StringBuilder(1024);
for (int i = -45; i <= 45; i++)
{
var x = i.Repeat(-45, 45);
if (sb.Length > 0)
sb.Append(", ");
sb.Append(x);
}

Debug.Log(sb.ToString());

-45, -44, -43, -42, -41, -40, -39, -38, -37, -36, -35, -34, -33, -32, -31, -30, -29, -28, -27, -26, -25, -24, -23, -22, -21, -20, -19, -18, -17, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 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

 注意点としては、値の上限(max)を「含まない」という点だ。

 この例の場合、max = 45 のため「…, 43, 44, -45, -44, …」のように値がループする。



●下限~上限(を含む)範囲を返す Mathf.Repeat
using UnityEngine;

public static class MathfExtentions //※クラス名は任意
{
/// <summary>
/// 下限~上限(を含む)範囲を返す Mathf.Repeat
/// 2020/12/20 Fantom
/// http://fantom1x.blog130.fc2.com/blog-entry-390.html
/// </summary>
/// <param name="value">元の値</param>
/// <param name="min">下限 (inclusive)</param>
/// <param name="max">上限 (inclusive)</param>
/// <returns>min(inclusive)~max(inclusive) の Mathf.Repeat</returns>
public static float RepeatInclusive(this float value, float min, float max)
{
return (value == max) ? max : Repeat(value, min, max); //※「下限~上限(を含まない)」関数が必要
}

//int 版
public static int RepeatInclusive(this int value, int min, int max)
{
return (value == max) ? max : Repeat(value, min, max);
}
}

●メインコード例
using UnityEngine;
using System.Text;

var sb = new StringBuilder(1024);
for (int i = -45; i <= 45; i++)
{
var x = i.RepeatInclusive(-45, 45);
if (sb.Length > 0)
sb.Append(", ");
sb.Append(x);
}

Debug.Log(sb.ToString());

-45, -44, -43, -42, -41, -40, -39, -38, -37, -36, -35, -34, -33, -32, -31, -30, -29, -28, -27, -26, -25, -24, -23, -22, -21, -20, -19, -18, -17, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 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

 注意点としては、値の上限(max)を「含む」という点だ。関数内部で前述の「下限~上限(を含まない)」版も利用している。

 この例の場合、max = 45 のため「…, 43, 44, 45, -44, …」のように値がループする。

 また、値の意味としては「-45 と 45 は同値扱い」となる。これは我々の感覚として「-180度 と 180 度が同じ」のように使えるわけで、特に UI において、ユーザーから値を指定してもらう際には便利になる(-180~179 度でも良いが、-180~180 度の方が、人の感覚としてはわかり易い)。

 UI の実例としてはスライダー等に使うとわかり易いね。大したものではないが、意外と利用頻度は高いと思う。







(関連記事)
【Unity】【C#】倍数での Floor, Ceil, Round(一定間隔での切り捨て、切り上げ、四捨五入) [float 版]
【C#】最大公約数を求める/分数の約分をする(ユークリッドの互除法)
【Java】最大公約数・最小公倍数を求める(ユークリッドの互除法)
【Java】3つ以上の最大公約数を求める(ユークリッドの互除法②)
【Java】拡張ユークリッドの互除法


関連記事
スポンサーサイト



category: Unity

thread: ゲーム開発

janre: コンピュータ

tag: Unityライブラリ  Unityリファレンス  算術関数 
tb: 0   cm: --


プロフィール

Social

検索フォーム

全記事一覧

カテゴリ

ユーザータグ

最新記事

リンク

PR

▲ Pagetop