2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Unity C#】インデックスを循環的に制限する

2
Last updated at Posted at 2025-11-06

選択UIなどで、配列のインデックスを循環させることがよくあります。
以下の計算が有名です。

int i;    // インデックス
int diff; // 変化させる値
int len;  // 配列の長さ

i = (i + diff) % len;
i = (i - diff + len) % len;

しかし私としては、この処理は汎用性が低いと感じています。
なぜなら、負数に対する剰余がちょっと癖強いからです。

成功ケース
int i    = 2;
int diff = 4;
int len  = 5;

i = (i + diff) % len;       // 1
i = (i - diff + len) % len; // 3
失敗ケース
int i    = 2;
int diff = 10;
int len  = 5;

i = (i + diff) % len;       // 2
i = (i - diff + len) % len; // -3 (-3 % 5 != 2)

負数への対応を強化する場合、次のように出来るでしょう。

失敗ケース リベンジ!
int i    = 2;
int diff = 10;
int len  = 5;

i = (i + diff) % len;               // 2
i = ((i - diff) % len + len) % len; // 2

もうちょっと汎用性を高めてみます。
先ほどまでは [0, len) の区間でしたが、
これを [begin, end) の任意区間に対応させてみます。

考え方としては、

  1. begin を引いて 一旦 [0, end-begin) の区間にずらし、
  2. 上述の計算を行った後、
  3. begin を足して [begin, end) の区間に戻す

感じです。

それと、もう diff は見なくていいですね。任意整数に対しての計算が出来るので。

任意区間に対応したバージョン
int i     = 12
int begin = 4;
int end   = 7;

// 0. 区間の長さを求めておく
int len = end - begin;

// 1. begin を引く
// この後剰余を取るので、ここでは必要ない
i -= begin;

// 2. 上述の計算
i = (i % len + len) % len;

// この段階で 0 <= i < (end-begin) になる

// 3. begin を足す
// begin <= i < end になるので、更なる剰余の計算は必要ない
i += begin; // つまり i = (i + begin) % len としなくて良い

// 計算結果 : 6

これまで述べた内容を、拡張メソッドにしてみました。
Pure C# でも同様に使えると思います。

完成版
using System.Runtime.CompilerServices;

public static class MathUtils
{
    /// <summary>
    /// 値を循環的に制限する
    /// </summary>
    /// <param name="value">値</param>
    /// <param name="begin">最小値</param>
    /// <param name="end">最大値 + 1</param>
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static int ModClamped(this int value, int begin, int end)
    {
        int len = end - begin;
        return ((value - begin) % len + len) % len + begin;
    }
}

使用例

_ = -1.ModClamped(0, 5); // 4
_ =  6.ModClamped(1, 5); // 2
2
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?