C#でランダムな数値を簡単生成!Random.Rangeの使い方と注意点を徹底解説

はじめに

C#でランダムな数値を生成したいとき、「Random.Rangeを使えばよい」と考える人は多いでしょう。特にUnityでゲーム開発をしている場合、敵の出現位置、アイテムのドロップ確率、キャラクターの能力値、演出の揺らぎなど、ランダム処理は非常によく使われます。

ただし、ここで注意したいのは、Random.RangeはC#標準の機能ではなく、Unityで使えるメソッドだという点です。通常のC#コンソールアプリや.NETアプリでそのままRandom.Rangeと書いても、基本的には使用できません。

C#標準環境ではSystem.Randomを使い、UnityではUnityEngine.Random.Rangeを使う、という違いを理解しておくことが大切です。

この記事では、C#でランダムな数値を扱いたい人に向けて、Random.Rangeの基本的な使い方、int型とfloat型で異なる注意点、Unity以外での乱数生成方法、よくあるエラー、実践的な活用例まで詳しく解説します。

1. C#のRandom.Rangeとは?まず押さえる基礎知識

1-1. Random.RangeはC#標準機能ではなくUnityのメソッド

Random.Rangeは、Unityで用意されている乱数生成メソッドです。正式にはUnityEngine.Random.Rangeとして提供されており、Unityプロジェクト内でランダムな値を生成するときによく使われます。

たとえば、Unityでは次のように書けます。

C#
int number = Random.Range(0, 10);

このコードは、0以上10未満の整数をランダムに生成します。

一方で、通常のC#コンソールアプリケーションで同じコードを書くと、Random.Rangeが存在しないというエラーになることがあります。これは、Random.RangeがC#言語そのものの機能ではなく、UnityのAPIだからです。

そのため、「C# random.range」で検索している場合は、自分がUnityで開発しているのか、それとも通常のC#環境で開発しているのかを最初に確認しましょう。

1-2. C#標準の乱数生成はSystem.Randomを使う

Unity以外のC#環境では、一般的にSystem.Randomクラスを使って乱数を生成します。

C#
Random random = new Random();
int number = random.Next(0, 10);

このコードでは、0以上10未満の整数が生成されます。

UnityのRandom.RangeとC#標準のRandom.Nextは似ていますが、使える環境や書き方が異なります。特に、UnityではRandom.Rangeをよく使い、通常のC#ではSystem.Randomを使うと覚えておくと混乱しにくくなります。

1-3. 検索ユーザーが混同しやすいRandom.RangeとRandom.Nextの違い

Random.RangeRandom.Nextは、どちらもランダムな数値を作るための機能ですが、次のような違いがあります。

Random.RangeはUnityで使うメソッドです。整数だけでなく小数の乱数も簡単に生成できます。

C#
int value = Random.Range(1, 6);
float rate = Random.Range(0.0f, 1.0f);

一方、Random.NextはC#標準のSystem.Randomで使うメソッドです。主に整数の乱数を生成します。

C#
Random random = new Random();
int value = random.Next(1, 6);

また、小数を生成する場合はNextDoubleを使います。

C#
double rate = random.NextDouble();

名前は似ていませんが、役割は近いため、Unity初心者やC#初心者が混同しやすいポイントです。

1-4. Random.Rangeが使われる主な場面

Random.Rangeは、Unityのゲーム開発で特によく使われます。主な用途は次のような場面です。

敵の出現位置をランダムに決める場合、X座標やZ座標をRandom.Rangeで生成できます。

C#
float x = Random.Range(-5.0f, 5.0f);
float z = Random.Range(-5.0f, 5.0f);

アイテムのドロップ確率を決める場合にも使えます。

C#
int dropRate = Random.Range(0, 100);

キャラクターの攻撃力にばらつきを持たせることもできます。

C#
int damage = Random.Range(8, 13);

このように、ゲーム内に予測できない変化を加えたいときにRandom.Rangeは非常に便利です。

2. Random.Rangeの基本的な使い方

2-1. Random.Rangeの基本構文

Unityで使うRandom.Rangeの基本構文は次のとおりです。

C#
Random.Range(最小値, 最大値);

整数を生成する場合は、引数にint型の値を渡します。

C#
int value = Random.Range(0, 10);

小数を生成する場合は、引数にfloat型の値を渡します。

C#
float value = Random.Range(0.0f, 10.0f);

ここで重要なのは、int型とfloat型で最大値を含むかどうかが異なる点です。この違いは後ほど詳しく解説します。

2-2. 整数のランダム値を生成する方法

整数のランダム値を生成するには、次のように書きます。

C#
int number = Random.Range(1, 6);

この場合、生成される可能性がある値は次のとおりです。

C#
1, 2, 3, 4, 5

最大値として指定した6は含まれません。

サイコロのように1〜6の値を出したい場合は、次のように最大値を7にします。

C#
int dice = Random.Range(1, 7);

このコードでは、1以上7未満、つまり1〜6の整数が生成されます。

2-3. 小数のランダム値を生成する方法

小数のランダム値を生成するには、float型の値を引数に指定します。

C#
float value = Random.Range(0.0f, 1.0f);

この場合、0.0以上1.0以下のランダムな小数が生成されます。

たとえば、キャラクターの移動速度をランダムにしたい場合は、次のように書けます。

C#
float speed = Random.Range(3.0f, 6.0f);

このコードでは、3.0〜6.0の範囲でランダムな小数が生成されます。

C#では小数リテラルにfを付けることでfloat型として扱えます。3.0だけだとdouble型として扱われるため、UnityのRandom.Rangefloatを使う場合は3.0fのように書くのが一般的です。

2-4. 変数に代入して使う基本サンプル

Random.Rangeで生成した値は、変数に代入して使うのが基本です。

C#
using UnityEngine;

public class RandomSample : MonoBehaviour
{
void Start()
{
int randomNumber = Random.Range(0, 10);
Debug.Log(randomNumber);
}
}

このコードをUnityで実行すると、ゲーム開始時に0〜9のランダムな整数がコンソールに表示されます。

小数の場合は次のように書きます。

C#
using UnityEngine;

public class RandomFloatSample : MonoBehaviour
{
void Start()
{
float randomValue = Random.Range(0.0f, 5.0f);
Debug.Log(randomValue);
}
}

このコードでは、0.0〜5.0の範囲でランダムな小数が表示されます。

2-5. コンソールやDebug.Logで結果を確認する方法

UnityでRandom.Rangeの結果を確認するときは、Debug.Logを使います。

C#
Debug.Log(Random.Range(0, 10));

複数回確認したい場合は、for文を使うと便利です。

C#
using UnityEngine;

public class RandomCheck : MonoBehaviour
{
void Start()
{
for (int i = 0; i < 10; i++)
{
int number = Random.Range(0, 10);
Debug.Log(number);
}
}
}

このコードでは、0〜9のランダムな整数が10回表示されます。

意図した範囲の値が出ているかを確認したいときは、まずDebug.Logで出力して検証するのがおすすめです。

3. int型とfloat型で変わるRandom.Rangeの注意点

3-1. int型のRandom.Rangeは最大値を含まない

Random.Rangeで特に注意すべき点は、int型の場合、最大値を含まないことです。

C#
int value = Random.Range(0, 10);

この場合、生成される値は0〜9です。10は出ません。

これは、配列やリストのインデックスを扱うときには便利です。

C#
string[] names = { "Alice", "Bob", "Charlie" };

int index = Random.Range(0, names.Length);
Debug.Log(names[index]);

配列のインデックスは0から始まり、最後の要素はLength - 1です。そのため、Random.Range(0, names.Length)と書くことで、配列の範囲内から安全にランダムな要素を選べます。

3-2. float型のRandom.Rangeは最大値を含む

一方、float型のRandom.Rangeは最大値を含みます。

C#
float value = Random.Range(0.0f, 10.0f);

この場合、0.0〜10.0の範囲の小数が生成されます。

整数版と小数版で最大値の扱いが異なるため、次のように覚えておくとよいでしょう。

C#
Random.Range(0, 10);       // int版:0以上10未満
Random.Range(0.0f, 10.0f); // float版:0.0以上10.0以下

この違いを理解していないと、「最大値が出ない」「思った範囲と違う」と感じる原因になります。

3-3. 0〜10の乱数を作るときの具体例

0〜10の整数を生成したい場合は、最大値に11を指定します。

C#
int value = Random.Range(0, 11);

これで生成される値は次の範囲になります。

C#
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

一方、0.0〜10.0の小数を生成したい場合は、次のように書きます。

C#
float value = Random.Range(0.0f, 10.0f);

整数の場合は最大値を含めたいなら1足す、小数の場合はそのまま指定する、と考えるとわかりやすいです。

3-4. 範囲指定でよくあるミスと対処法

よくあるミスのひとつは、サイコロの値を作るときに次のように書いてしまうことです。

C#
int dice = Random.Range(1, 6);

このコードでは、1〜5しか出ません。6を出したい場合は次のようにします。

C#
int dice = Random.Range(1, 7);

もうひとつのミスは、配列のランダム選択で最大値にLength - 1を指定してしまうことです。

C#
int index = Random.Range(0, items.Length - 1);

この場合、最後の要素が選ばれなくなります。正しくは次のように書きます。

C#
int index = Random.Range(0, items.Length);

int型のRandom.Rangeでは最大値が含まれないため、配列やリストではLengthCountをそのまま指定するのが基本です。

4. C#標準環境でランダムな数値を生成する方法

4-1. System.Randomの基本構文

Unityではなく、C#のコンソールアプリやWindowsアプリ、ASP.NETなどでランダムな数値を生成する場合は、System.Randomを使います。

基本構文は次のとおりです。

C#
Random random = new Random();

乱数を生成するときは、このrandomインスタンスを使います。

C#
int number = random.Next();

通常は、範囲を指定して使うことが多いです。

C#
int number = random.Next(0, 10);

この場合、0以上10未満の整数が生成されます。

4-2. Random.Nextで整数を生成する方法

Random.Nextを使うと、整数の乱数を生成できます。

C#
Random random = new Random();

int value = random.Next(0, 10);
Console.WriteLine(value);

このコードでは、0〜9の整数が出力されます。

1〜6のサイコロのような値を作る場合は、次のように書きます。

C#
Random random = new Random();

int dice = random.Next(1, 7);
Console.WriteLine(dice);

Random.Next(minValue, maxValue)も、UnityのRandom.Rangeのint版と同じように、最大値を含みません。

4-3. Random.NextDoubleで小数を生成する方法

C#標準のSystem.Randomで小数を生成する場合は、NextDoubleを使います。

C#
Random random = new Random();

double value = random.NextDouble();
Console.WriteLine(value);

NextDoubleは、0.0以上1.0未満の小数を返します。

たとえば、確率判定に使う場合は次のように書けます。

C#
Random random = new Random();

double rate = random.NextDouble();

if (rate < 0.3)
{
Console.WriteLine("成功");
}
else
{
Console.WriteLine("失敗");
}

この例では、約30%の確率で「成功」と表示されます。

4-4. 指定範囲内の小数を生成する計算式

NextDoubleは0.0以上1.0未満の値しか返しません。指定した範囲の小数を作りたい場合は、計算式を使います。

C#
double min = 5.0;
double max = 10.0;

double value = min + random.NextDouble() * (max - min);

この式を使うと、5.0以上10.0未満の小数を生成できます。

メソッド化すると再利用しやすくなります。

C#
static double RangeDouble(Random random, double min, double max)
{
return min + random.NextDouble() * (max - min);
}

使うときは次のようにします。

C#
Random random = new Random();

double value = RangeDouble(random, 5.0, 10.0);
Console.WriteLine(value);

UnityのRandom.Rangeに近い感覚で、C#標準環境でも小数の範囲指定ができます。

4-5. Unity以外でRandom.Rangeが使えないときの解決策

Unity以外でRandom.Rangeが使えない場合は、System.Randomを使いましょう。

整数の場合は次のようにします。

C#
Random random = new Random();
int value = random.Next(0, 10);

小数の場合は次のようにします。

C#
Random random = new Random();

double min = 0.0;
double max = 10.0;
double value = min + random.NextDouble() * (max - min);

どうしてもRandom.Rangeのような書き方をしたい場合は、自分でメソッドを作ることもできます。

C#
static int Range(Random random, int min, int max)
{
return random.Next(min, max);
}

static double Range(Random random, double min, double max)
{
return min + random.NextDouble() * (max - min);
}

ただし、UnityのRandom.Rangeとは最大値の扱いが異なる場合があるため、自作する場合は仕様を明確にしておくことが重要です。

5. UnityでRandom.Rangeを活用する実践例

5-1. 敵の出現位置をランダムに決める

敵をランダムな位置に出現させたい場合、座標をRandom.Rangeで生成します。

C#
using UnityEngine;

public class EnemySpawner : MonoBehaviour
{
public GameObject enemyPrefab;

void Start()
{
float x = Random.Range(-8.0f, 8.0f);
float z = Random.Range(-5.0f, 5.0f);

Vector3 spawnPosition = new Vector3(x, 0.0f, z);

Instantiate(enemyPrefab, spawnPosition, Quaternion.identity);
}
}

このコードでは、X座標が-8.0〜8.0、Z座標が-5.0〜5.0の範囲でランダムに決まり、敵がその位置に生成されます。

2Dゲームの場合は、Vector2Vector3のX座標・Y座標をランダムにするとよいでしょう。

C#
float x = Random.Range(-5.0f, 5.0f);
float y = Random.Range(-3.0f, 3.0f);

Vector3 position = new Vector3(x, y, 0.0f);

5-2. アイテムのドロップ確率をランダムにする

アイテムのドロップ判定にもRandom.Rangeはよく使われます。

C#
int rate = Random.Range(0, 100);

if (rate < 30)
{
Debug.Log("アイテムをドロップ");
}
else
{
Debug.Log("ドロップなし");
}

この例では、0〜99の値を生成し、30未満ならドロップします。つまり、約30%の確率でアイテムが落ちる処理になります。

小数で判定する場合は、Random.valueRandom.Range(0.0f, 1.0f)を使うこともできます。

C#
float rate = Random.Range(0.0f, 1.0f);

if (rate < 0.3f)
{
Debug.Log("アイテムをドロップ");
}

確率を扱うときは、整数で0〜99を使う方法と、小数で0.0〜1.0を使う方法のどちらでも実装できます。チーム開発では、どちらの書き方に統一するかを決めておくと読みやすくなります。

5-3. キャラクターの移動速度や攻撃力にばらつきを出す

すべての敵が同じ速度や同じ攻撃力だと、ゲームが単調に感じられることがあります。Random.Rangeを使うと、自然なばらつきを加えられます。

C#
float speed = Random.Range(2.5f, 4.5f);

攻撃力をランダムにする例は次のとおりです。

C#
int attackPower = Random.Range(8, 13);

この場合、8〜12の整数が生成されます。

ダメージ計算に使う場合は、基準値にランダム補正を加える方法もあります。

C#
int baseDamage = 10;
int randomBonus = Random.Range(-2, 3);

int damage = baseDamage + randomBonus;

このコードでは、最終的なダメージは8〜12になります。

5-4. ランダムな色やサイズを設定する

オブジェクトの色をランダムに変えたい場合にもRandom.Rangeを使えます。

C#
using UnityEngine;

public class RandomColor : MonoBehaviour
{
void Start()
{
Renderer renderer = GetComponent<Renderer>();

float r = Random.Range(0.0f, 1.0f);
float g = Random.Range(0.0f, 1.0f);
float b = Random.Range(0.0f, 1.0f);

renderer.material.color = new Color(r, g, b);
}
}

サイズをランダムにする場合は、localScaleにランダムな値を設定します。

C#
float size = Random.Range(0.5f, 2.0f);
transform.localScale = new Vector3(size, size, size);

背景の装飾、エフェクト、敵キャラクターの見た目の違いなどに使うと、同じ素材でも変化のある表現ができます。

5-5. ゲーム演出に自然な変化を加える

Random.Rangeは、ゲーム演出に自然な揺らぎを加えるときにも役立ちます。

たとえば、効果音の音量を少し変える例です。

C#
AudioSource audioSource = GetComponent<AudioSource>();

audioSource.volume = Random.Range(0.8f, 1.0f);
audioSource.pitch = Random.Range(0.9f, 1.1f);

audioSource.Play();

同じ効果音を何度も再生すると単調に聞こえますが、音量やピッチを少し変えるだけで自然な印象になります。

パーティクルのサイズや発生位置にばらつきを出す場合にも使えます。

C#
float offsetX = Random.Range(-0.2f, 0.2f);
float offsetY = Random.Range(-0.2f, 0.2f);

Vector3 effectPosition = transform.position + new Vector3(offsetX, offsetY, 0.0f);

ランダム処理は、ゲームの手触りを良くするためにも重要なテクニックです。

6. Random.Rangeでよくあるエラーと原因

6-1. Random.Rangeが存在しないと表示される原因

Random.Rangeが存在しないと表示される主な原因は、Unity以外のC#環境で使おうとしていることです。

たとえば、通常のC#コンソールアプリで次のように書くとエラーになることがあります。

C#
int value = Random.Range(0, 10);

C#標準のSystem.RandomにはRangeというメソッドはありません。そのため、Unity以外では次のように書きます。

C#
Random random = new Random();
int value = random.Next(0, 10);

Unityで開発している場合は、UnityEngine.Random.Rangeが使えます。

6-2. using UnityEngineが不足しているケース

UnityでRandom.Rangeを使う場合、ファイルの先頭にusing UnityEngine;が必要です。

C#
using UnityEngine;

public class RandomSample : MonoBehaviour
{
void Start()
{
int value = Random.Range(0, 10);
Debug.Log(value);
}
}

using UnityEngine;がない場合は、次のように完全修飾名で書くこともできます。

C#
int value = UnityEngine.Random.Range(0, 10);

特にSystem.Randomと混在しているコードでは、完全修飾名を使うと意図が明確になります。

6-3. System.RandomとUnityEngine.Randomの名前衝突

Unityで次のように書くと、Randomという名前が衝突することがあります。

C#
using System;
using UnityEngine;

System.RandomUnityEngine.Randomの両方が存在するため、どちらのRandomを指しているのか曖昧になる場合があります。

このようなときは、完全修飾名を使いましょう。

C#
int value = UnityEngine.Random.Range(0, 10);

C#標準のSystem.Randomを使いたい場合は次のようにします。

C#
System.Random random = new System.Random();
int value = random.Next(0, 10);

Unityの乱数とC#標準の乱数を同じファイルで使う場合は、明示的に書き分けるとエラーを防ぎやすくなります。

6-4. 引数の型が合わない場合のエラー

Random.Rangeは、引数の型によって整数版と小数版が切り替わります。

C#
int value = Random.Range(0, 10);
float value2 = Random.Range(0.0f, 10.0f);

整数を返したい場合はintを使い、小数を返したい場合はfloatを使います。

次のように、戻り値の型と代入先の型が合っていないとエラーになることがあります。

C#
int value = Random.Range(0.0f, 10.0f);

この場合、Random.Range(0.0f, 10.0f)floatを返すため、int型の変数にはそのまま代入できません。

整数にしたい場合は、最初から整数版を使います。

C#
int value = Random.Range(0, 10);

または、必要に応じて丸め処理を行います。

C#
int value = Mathf.FloorToInt(Random.Range(0.0f, 10.0f));

ただし、単純に整数の乱数が欲しいだけなら、Random.Range(int, int)を使う方がわかりやすいです。

6-5. 意図した範囲の数値が出ない原因

意図した範囲の数値が出ない原因として最も多いのは、最大値を含むかどうかの誤解です。

C#
int value = Random.Range(0, 10);

このコードでは10は出ません。0〜10を出したい場合は次のようにします。

C#
int value = Random.Range(0, 11);

また、マイナスの範囲を指定するときにも注意が必要です。

C#
int value = Random.Range(-5, 6);

この場合、-5〜5の整数が生成されます。

「最大値が出ない」「最後の配列要素が選ばれない」「サイコロで6が出ない」といった問題は、ほとんどの場合、範囲指定を見直すことで解決できます。

7. Random.Rangeを使うときの注意点

7-1. 毎フレーム呼び出す場合の負荷に注意する

Random.Range自体は便利なメソッドですが、Updateの中で毎フレーム大量に呼び出す場合は注意が必要です。

C#
void Update()
{
float value = Random.Range(0.0f, 1.0f);
}

少数回であれば大きな問題になることは少ないですが、大量のオブジェクトが毎フレーム乱数を生成し続けると、処理負荷や管理のしにくさにつながる場合があります。

必要なタイミングだけ乱数を生成するようにしましょう。

C#
void Start()
{
float speed = Random.Range(2.0f, 5.0f);
}

敵の出現時、攻撃時、アイテム生成時など、乱数が必要なイベントに合わせて呼び出すと効率的です。

7-2. 乱数の偏りを誤解しない

ランダムな値は、短い回数だけ見ると偏っているように感じることがあります。

たとえば、サイコロを10回振っただけでは、1が何度も出たり、6が一度も出なかったりすることがあります。しかし、それは必ずしも不具合ではありません。

C#
for (int i = 0; i < 10; i++)
{
Debug.Log(Random.Range(1, 7));
}

乱数は、回数が少ないほど偏って見えやすいものです。確率が正しいか確認したい場合は、試行回数を増やして検証しましょう。

C#
int count = 0;

for (int i = 0; i < 10000; i++)
{
int value = Random.Range(0, 100);

if (value < 30)
{
count++;
}
}

Debug.Log(count);

このように大量に試すことで、確率の傾向を確認しやすくなります。

7-3. シード値を使って再現性を持たせる方法

ゲーム開発では、毎回同じランダム結果を再現したい場合があります。たとえば、マップ生成、リプレイ機能、デバッグなどです。

Unityでは、Random.InitStateを使ってシード値を設定できます。

C#
Random.InitState(12345);

int value1 = Random.Range(0, 100);
int value2 = Random.Range(0, 100);

Debug.Log(value1);
Debug.Log(value2);

同じシード値を使うと、同じ順番で乱数が生成されます。

C#標準のSystem.Randomでは、コンストラクタにシード値を渡します。

C#
Random random = new Random(12345);

int value1 = random.Next(0, 100);
int value2 = random.Next(0, 100);

Console.WriteLine(value1);
Console.WriteLine(value2);

ランダム処理をデバッグしやすくしたい場合は、シード値を活用すると便利です。

7-4. セキュリティ用途には使わない

Random.RangeSystem.Randomは、ゲームや一般的なランダム処理には便利ですが、セキュリティ用途には向いていません。

たとえば、パスワード生成、認証トークン、暗号鍵、ワンタイムコードなどには使用しない方が安全です。

セキュリティ用途で乱数が必要な場合は、C#ではRandomNumberGeneratorなど、暗号学的に安全な乱数生成機能を使います。

C#
using System.Security.Cryptography;

byte[] bytes = new byte[16];
RandomNumberGenerator.Fill(bytes);

ゲーム内の演出や確率処理にはRandom.Range、セキュリティが関係する処理には暗号学的乱数、と使い分けることが重要です。

7-5. デバッグしやすい乱数処理の書き方

ランダム処理は、結果が毎回変わるため、バグの原因を追いにくいことがあります。デバッグしやすくするには、乱数生成部分を関数化したり、ログを出したりすると効果的です。

C#
int GetRandomDamage()
{
int damage = Random.Range(8, 13);
Debug.Log("Damage: " + damage);
return damage;
}

また、シード値を固定して再現性を持たせる方法も有効です。

C#
void Start()
{
Random.InitState(100);

int damage = GetRandomDamage();
}

複雑なランダム処理を直接あちこちに書くのではなく、メソッドにまとめることで、修正やテストがしやすくなります。

8. Random.Rangeと関連メソッドの比較

8-1. Random.RangeとRandom.Nextの違い

Random.RangeはUnityで使うメソッド、Random.NextはC#標準のSystem.Randomで使うメソッドです。

Unityの場合は次のように書きます。

C#
int value = Random.Range(0, 10);

C#標準では次のように書きます。

C#
Random random = new Random();
int value = random.Next(0, 10);

どちらも整数の場合は、最大値を含みません。

C#
Random.Range(0, 10); // 0〜9
random.Next(0, 10); // 0〜9

ただし、Random.RangeはUnity専用であり、Random.NextはUnity以外のC#環境でも使えるという違いがあります。

8-2. UnityEngine.RandomとSystem.Randomの違い

UnityEngine.RandomはUnityが提供する乱数機能です。ゲーム開発で使いやすく、Random.RangeRandom.valueなどが用意されています。

C#
int value = UnityEngine.Random.Range(0, 10);

System.Randomは.NET標準の乱数クラスです。Unity以外のC#アプリケーションでも使えます。

C#
System.Random random = new System.Random();
int value = random.Next(0, 10);

Unityプロジェクト内でもSystem.Randomを使うことはできますが、Unityの機能と混同しやすいため、必要に応じて完全修飾名で書くと安全です。

8-3. Random.valueとの違い

UnityにはRandom.Rangeのほかに、Random.valueもあります。

C#
float value = Random.value;

Random.valueは、0.0〜1.0の範囲のランダムな小数を返します。

確率判定では、次のように使えます。

C#
if (Random.value < 0.3f)
{
Debug.Log("30%の確率で成功");
}

Random.Rangeは範囲を指定できるのに対し、Random.valueは0.0〜1.0の範囲に特化しています。

C#
Random.Range(5.0f, 10.0f); // 5.0〜10.0の小数
Random.value; // 0.0〜1.0の小数

確率判定だけならRandom.value、任意の範囲を指定したいならRandom.Rangeが使いやすいです。

8-4. Range・Next・NextDoubleの使い分け

Unityで整数や小数の乱数を生成したい場合は、Random.Rangeを使います。

C#
int number = Random.Range(0, 10);
float value = Random.Range(0.0f, 10.0f);

通常のC#で整数を生成したい場合は、Random.Nextを使います。

C#
Random random = new Random();
int number = random.Next(0, 10);

通常のC#で小数を生成したい場合は、Random.NextDoubleを使います。

C#
double value = random.NextDouble();

指定範囲の小数が必要な場合は、計算式を組み合わせます。

C#
double min = 5.0;
double max = 10.0;

double value = min + random.NextDouble() * (max - min);

開発環境と欲しい値の型によって、適切なメソッドを選びましょう。

8-5. 用途別におすすめの乱数生成方法

Unityでゲームオブジェクトの位置、速度、色、確率などを決めるなら、Random.Rangeが最も使いやすいです。

C#
float x = Random.Range(-5.0f, 5.0f);

Unityで0.0〜1.0の確率判定をするだけなら、Random.valueが簡潔です。

C#
if (Random.value < 0.5f)
{
Debug.Log("50%の確率で実行");
}

C#標準環境で整数を生成するなら、System.Random.Nextを使います。

C#
Random random = new Random();
int value = random.Next(0, 10);

C#標準環境で小数を生成するなら、NextDoubleを使います。

C#
double value = random.NextDouble();

セキュリティ用途では、Random.RangeSystem.Randomではなく、RandomNumberGeneratorを使いましょう。

9. Random.Rangeの応用テクニック

9-1. 配列やリストからランダムに要素を選ぶ

配列からランダムに要素を選ぶ場合は、インデックスをRandom.Rangeで生成します。

C#
string[] items = { "Sword", "Shield", "Potion" };

int index = Random.Range(0, items.Length);
string selectedItem = items[index];

Debug.Log(selectedItem);

リストの場合は、Countを使います。

C#
List<string> enemies = new List<string>
{
"Slime",
"Goblin",
"Dragon"
};

int index = Random.Range(0, enemies.Count);
string enemy = enemies[index];

Debug.Log(enemy);

Random.Range(0, items.Length)のように書けるのは、int版の最大値が含まれないためです。最後の要素まで正しく選ばれます。

9-2. 確率を指定して処理を分岐する

確率で処理を分けたい場合は、0〜99の整数を使う方法がわかりやすいです。

C#
int rate = Random.Range(0, 100);

if (rate < 10)
{
Debug.Log("レアアイテム");
}
else if (rate < 40)
{
Debug.Log("通常アイテム");
}
else
{
Debug.Log("アイテムなし");
}

この例では、0〜9ならレアアイテム、10〜39なら通常アイテム、それ以外ならアイテムなしになります。

小数を使う場合は次のように書けます。

C#
float rate = Random.value;

if (rate < 0.1f)
{
Debug.Log("レアアイテム");
}
else if (rate < 0.4f)
{
Debug.Log("通常アイテム");
}
else
{
Debug.Log("アイテムなし");
}

確率を扱うときは、条件の境界をわかりやすく書くことが大切です。

9-3. 重複しないランダム値を生成する

重複しないランダム値を作りたい場合は、リストをシャッフルする方法が便利です。

C#
List<int> numbers = new List<int>();

for (int i = 0; i < 10; i++)
{
numbers.Add(i);
}

for (int i = 0; i < numbers.Count; i++)
{
int randomIndex = Random.Range(i, numbers.Count);

int temp = numbers[i];
numbers[i] = numbers[randomIndex];
numbers[randomIndex] = temp;
}

foreach (int number in numbers)
{
Debug.Log(number);
}

このコードでは、0〜9の数値をランダムな順番に並べ替えます。カードの山札、ランダムな出題順、重複なしの抽選などに使えます。

単純に何度もRandom.Rangeを呼んで重複チェックする方法もありますが、数が多い場合はシャッフルの方が扱いやすいです。

9-4. ランダムな座標を生成する

ランダムな座標を作る場合は、X、Y、ZそれぞれにRandom.Rangeを使います。

C#
float x = Random.Range(-10.0f, 10.0f);
float y = Random.Range(0.0f, 5.0f);
float z = Random.Range(-10.0f, 10.0f);

Vector3 position = new Vector3(x, y, z);

2Dゲームなら、XとYだけを使うことが多いです。

C#
float x = Random.Range(-8.0f, 8.0f);
float y = Random.Range(-4.0f, 4.0f);

Vector3 position = new Vector3(x, y, 0.0f);

ランダムな座標を使うときは、画面外や壁の中など、出現してはいけない場所に配置されないように注意しましょう。必要に応じて、当たり判定やNavMeshなどと組み合わせて安全な位置を選ぶこともあります。

9-5. ランダム処理を関数化して再利用する

同じようなランダム処理を何度も書く場合は、関数化すると便利です。

C#
int GetRandomDamage()
{
return Random.Range(8, 13);
}

使うときは次のようにします。

C#
int damage = GetRandomDamage();

確率判定も関数化できます。

C#
bool IsSuccess(float probability)
{
return Random.value < probability;
}

使用例は次のとおりです。

C#
if (IsSuccess(0.3f))
{
Debug.Log("成功");
}
else
{
Debug.Log("失敗");
}

関数化しておくと、処理の意味がわかりやすくなり、変更にも強くなります。

10. Random.Rangeに関するよくある質問

10-1. Random.Rangeで最大値が出ないのはなぜ?

int型のRandom.Rangeでは、最大値が含まれない仕様だからです。

C#
int value = Random.Range(0, 10);

この場合、生成される値は0〜9です。10は出ません。

0〜10を出したい場合は、最大値に11を指定します。

C#
int value = Random.Range(0, 11);

一方で、float型のRandom.Rangeでは最大値を含みます。

C#
float value = Random.Range(0.0f, 10.0f);

整数と小数で最大値の扱いが違う点に注意しましょう。

10-2. C#だけでRandom.Rangeは使える?

通常のC#だけでは、基本的にRandom.Rangeは使えません。Random.RangeはUnityのUnityEngine.Randomに含まれるメソッドです。

C#標準環境では、次のようにSystem.Randomを使います。

C#
Random random = new Random();
int value = random.Next(0, 10);

小数が必要な場合は、NextDoubleを使います。

C#
double value = random.NextDouble();

UnityであればRandom.Range、Unity以外であればSystem.Randomと覚えておきましょう。

10-3. 0か1をランダムに出すには?

Unityで0か1をランダムに出したい場合は、次のように書きます。

C#
int value = Random.Range(0, 2);

int版のRandom.Rangeは最大値を含まないため、0以上2未満、つまり0か1が生成されます。

真偽値として使いたい場合は、次のように書くこともできます。

C#
bool result = Random.Range(0, 2) == 0;

または、Random.valueを使って次のように書けます。

C#
bool result = Random.value < 0.5f;

どちらも約50%の確率でtrueまたはfalseになります。

10-4. マイナスの範囲も指定できる?

Random.Rangeでは、マイナスの範囲も指定できます。

C#
int value = Random.Range(-5, 6);

このコードでは、-5〜5の整数が生成されます。

小数の場合も同様です。

C#
float value = Random.Range(-1.0f, 1.0f);

このコードでは、-1.0〜1.0の範囲の小数が生成されます。

座標のランダム化では、マイナスの範囲を使うことがよくあります。

C#
float x = Random.Range(-10.0f, 10.0f);
float z = Random.Range(-10.0f, 10.0f);

10-5. 同じ乱数結果を再現するには?

Unityでは、Random.InitStateを使ってシード値を固定します。

C#
Random.InitState(123);

int value1 = Random.Range(0, 100);
int value2 = Random.Range(0, 100);

Debug.Log(value1);
Debug.Log(value2);

同じシード値を指定すれば、同じ順番で乱数が生成されます。

C#標準のSystem.Randomでは、コンストラクタにシード値を渡します。

C#
Random random = new Random(123);

int value1 = random.Next(0, 100);
int value2 = random.Next(0, 100);

Console.WriteLine(value1);
Console.WriteLine(value2);

デバッグや自動生成マップ、リプレイ機能など、同じ結果を再現したい場面ではシード値を活用しましょう。

まとめ

C#でランダムな数値を生成したい場合、まず理解しておきたいのは、Random.RangeはC#標準機能ではなくUnityのメソッドだという点です。UnityではUnityEngine.Random.Rangeを使い、通常のC#環境ではSystem.Randomを使います。

UnityのRandom.Rangeは、整数と小数で最大値の扱いが異なります。

C#
Random.Range(0, 10);       // int版:0〜9
Random.Range(0.0f, 10.0f); // float版:0.0〜10.0

整数版では最大値を含まないため、サイコロで1〜6を出したい場合は次のように書きます。

C#
int dice = Random.Range(1, 7);

配列やリストからランダムに要素を選ぶ場合は、最大値にLengthCountを指定します。

C#
int index = Random.Range(0, items.Length);

Unity以外のC#では、整数ならRandom.Next、小数ならRandom.NextDoubleを使います。

C#
Random random = new Random();

int number = random.Next(0, 10);
double value = random.NextDouble();

Random.Rangeは、敵の出現位置、アイテムのドロップ率、キャラクターの能力値、ランダムな色やサイズ、ゲーム演出の変化など、さまざまな場面で活用できます。

ただし、最大値の扱い、System.Randomとの名前衝突、using UnityEngineの不足、セキュリティ用途には使わないことなどには注意が必要です。

Unityでランダム処理を書くならRandom.Rangeを正しく理解し、C#標準環境ではSystem.Randomを使い分けることで、意図した範囲の乱数を安全かつわかりやすく生成できるようになります。