fc2ブログ
ヽ|∵|ゝ(Fantom) の 開発blog? ホーム »
最近の記事

【Unity】【C#】double型の Clamp (拡張メソッド)  


 前回 double型の Repeat を作ったので、よく使うものとして、ついでに Clamp も定義しておく。といっても、めちゃくちゃ簡単なので、誰でも作れるものだけどね。

(※) Unity 2020.3.34f1 / Windows11(x64) で確認

●double 型の Clamp 拡張メソッド
using System;

public static partial class MathExtensions //※クラス名は任意
{
/// <summary>
/// double での Clamp.
/// 2024/02/18 Fantom
/// http://fantom1x.blog130.fc2.com/blog-entry-438.html
/// </summary>
/// <param name="value">元の値</param>
/// <param name="min">下限値 (inclusive)</param>
/// <param name="max">上限値 (inclusive)</param>
/// <returns></returns>
public static double Clamp(this double value, double min, double max)
{
if (value < min) return min;
if (max < value) return max;
return value;
}
}

●メインコードでの使用例
using UnityEngine;

Debug.Log(12.0.Clamp(0.0, 5.0)); //5
Debug.Log((-12.0).Clamp(0.0, 5.0)); //0

 Repeat と違い、上限値を"含む"(inclusive) なので注意。上限値を上回ったときや、下限値を下回ったときに、下限~上限値に収める関数だね。よく使うものなので関数として定義した方が楽だと思うが、一行で簡単に書きたいなら、Math クラスの Min, Max を使っても同じことができる。

●Math クラスの Min, Max を使って Clamp と同じことをする
using System;

var value = Math.Max(min, Math.Min(max, value));

 Unity のライブラリみたいに 0~1 に収める Mathf.Clamp01 みたいのを作っても良いね。これはオーバーロードでも良いだろう。Unity には無いが、0~100 なんてのもよく使うので、Clamp0100 みたいのも定義すると便利かもね。

●Clamp01, Clamp0100 を定義する(Clamp のオーバーロード)
using System;

public static partial class MathExtensions //※クラス名は任意
{
/// <summary>
/// double での Clamp01 (0~1).
/// 2024/02/18 Fantom
/// http://fantom1x.blog130.fc2.com/blog-entry-438.html
/// </summary>
/// <param name="value">元の値</param>
/// <returns></returns>
public static double Clamp01(this double value)
{
return Clamp(value, 0, 1);
}

/// <summary>
/// double での Clamp0100 (0~100).
/// 2024/02/18 Fantom
/// http://fantom1x.blog130.fc2.com/blog-entry-438.html
/// </summary>
/// <param name="value">元の値</param>
/// <returns></returns>
public static double Clamp0100(this double value)
{
return Clamp(value, 0, 100);
}
}

 とても地味な関数だけど、double に型変更したとき無いと不便なので、いつでも使えるようにライブラリ化しておくと便利。

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


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



category: Unity

thread: ゲーム開発

janre: コンピュータ

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

【Unity】【C#】double型の Repeat (拡張メソッド)  


 Unity には標準の算術関数:Math クラスを float 型にした Mathf クラスをよく用いるが、double 型だと使えないんだよね。なので、型変更したら関数も Math クラスにしないといけないのだが、全ての関数が一対一で用意されてるわけではない。Mathf.Repeat も Math クラスには無かった…。Repeat って Unity では結構使うこと多いし、ググっても実装例見つからなかったので、double 型でもあったら良いなと思って作った拡張メソッド。

(※) Unity 2020.3.34f1 / Windows11(x64) で確認

●double 型の Repeat 拡張メソッド
using System;

public static partial class MathExtensions //※クラス名は任意
{
/// <summary>
/// double での Repeat.
/// 2024/01/18 Fantom
/// http://fantom1x.blog130.fc2.com/blog-entry-437.html
/// </summary>
/// <param name="value">元の値</param>
/// <param name="length">上限値 (exclusive)[> 0]</param>
/// <returns></returns>
public static double Repeat(this double value, double length)
{
if (length <= 0)
{
throw new AggregateException($"length must be greater than 0 : length = {length}");
}

if (length <= value)
{
return value % length;
}
else if (value < 0)
{
return length - (-value) % length;
}
return value;
}
}

●メインコードでの使用例
using UnityEngine;

Debug.Log(12.0.Repeat(5.0)); //2
Debug.Log((-12.0).Repeat(5.0)); //3
Debug.Log((-12.0).Repeat(-5.0)); //AggregateException

 1つ注意点は、Mathf.Repeat のマニュアルにもあるが、length は 0 より大きい値でないといけない。なので、0 または負の長さはエラーをスローしている。
 これは単純に length が割り算の分母になるからもあるが、0 が分母に使えないのは無論のこと、負の値の剰余は言語によって違ってたりして信用できない値となるので、メソッドに使うのはオススメしない。これは全ての言語に関わることなので、覚えておいた方が良いだろう。以下に資料を載せておく。

(参考)
負数の剰余を計算してはならない

 あと、細かい事だが、例の中で Debug.Log で負の値をカッコで括ってるが("(-12.0).Repeat(5.0)")、付けないと("-12.0.Repeat(5.0)")関数の戻値にマイナスを掛けることになるので注意("-1 * (12.0.Repeat(5.0))"←みたいになる)。場合によっては、負の値にカッコを付けた方が見やすいこともあるね。


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


関連記事

category: Unity

thread: ゲーム開発

janre: コンピュータ

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

【Unity】【C#】CullingMask をレイヤー名でオン/オフする (拡張メソッド)  


 Light, Camera, ReflectionProbe 等にはレイヤー分けして効果の対象を選択できる CullingMask が設定できるけど、用例を見てると、地味にわかりずらいんだよね…(ビット演算で 1<<0 みたいな所)。

 なので、レイヤー名(文字列)で簡単に対象をオン/オフする拡張メソッドを作っておくと便利。ビット列ではないので、後でレイヤー番号を変更しても、文字列指定ならわかり易いしね。

(※) Unity 2020.3.34f1 / Windows11(x64) で確認

●Light コンポーネントの CullingMask のオン/オフをする拡張メソッド
using UnityEngine;

public static partial class Extensions //※クラス名は任意
{
/// <summary>
/// ライトの CullingMask のオン/オフ (LayerMask)
/// 2023/12/18 Fantom
/// http://fantom1x.blog130.fc2.com/blog-entry-436.html
/// </summary>
/// <param name="light">対象のライト</param>
/// <param name="mask">LayerMask.GetMask の値を入れる</param>
/// <param name="isOn">true = On / false = Off</param>
public static void SetCullingMask(this Light light, int mask, bool isOn)
{
if (light == null)
return;

if (isOn)
{
light.cullingMask |= mask; //ビットを OR でオンにする
}
else
{
light.cullingMask &= ~mask; //反転して、AND することで、ビットを 0 にする
}
}

/// <summary>
/// ライトの CullingMask のオン/オフ (レイヤー名)
/// 2023/12/18 Fantom
/// http://fantom1x.blog130.fc2.com/blog-entry-436.html
/// </summary>
/// <param name="light">対象のライト</param>
/// <param name="layerName">レイヤー名</param>
/// <param name="isOn">true = On / false = Off</param>
public static void SetCullingMask(this Light light, string layerName, bool isOn)
{
if (light == null || string.IsNullOrEmpty(layerName))
return;

SetCullingMask(light, LayerMask.GetMask(layerName), isOn);
}
}

●メインコードでの使用例
using UnityEngine;

public class SetCullingMaskTest : MonoBehaviour
{
public Light _light; //インスペクタでセットする

private void Start()
{
var layerName = "Character"; //Tag & Layers の名前(※任意)
_light.SetCullingMask(layerName, true);
}
}

 最初の「SetCullingMask(this Light, int, bool)」の int引数 はビット列(レイヤー番号)用のメソッドとなる。次の「SetCullingMask(this Light, string, bool)」の string引数 が本題のレイヤー名(※ここでは"Character")用のメソッドになる。内容的には「LayerMask.GetMask(layerName)」を挟んで、ビット列(レイヤー番号)用をオーバーロードしてる感じになる。文字列(レイヤー名)とオン/オフ(true/false)の引数なので、使い方も難しくはないだろう。Camera や ReflectionProbe も this~ の型を変えたメソッドを定義すれば、簡単に流用できる。

 ちなみにレイヤー名は「Tag & Layers」で自由に付けられる。インスペクタなどから [Layer>Add Layer...] で一覧を表示し、空いてる所に名前を入れれば良い(無効化されてるのはシステム予約のレイヤー)。

●[Layer>Add Layer...] で「Tag & Layers」を表示

●空いてる所に任意に名前を入れる

●メインコードでの使用例の結果(起動後のようになる)



(関連記事)
【Unity】【C#】Light の Halo はランタイム操作できない?
【Unity】Standard Assets の Flare (レンズフレア) は Gamma 用だった?
【Unity】【C#】指定ワールド位置がカメラに映っているか調べる
【Unity】【C#】固定背景画像(2D)を表示する


関連記事

category: Unity

thread: ゲーム開発

janre: コンピュータ

tag: Unityライブラリ  Unityリファレンス  C# 
tb: 0   cm: --


プロフィール

Social

検索フォーム

全記事一覧

カテゴリ

ユーザータグ

最新記事

リンク

PR

▲ Pagetop