【Unity】ランダムな値を取得する方法!乱数を使ってゲームを面白くしよう

ランダムな値を取得してみよう ゲーム開発

今回はUnity初心者の方向けの話題で、

Unityでランダムな値を取得する方法

を丁寧に解説していくという内容の記事になっています。

ゲームを作っていると

  • ランダムな座標に敵やアイテムを配置したい
  • ガチャのようなランダム抽選を行いたい

という場面があると思うのですが、そのようなときには「乱数」と呼ばれるものが活躍します。ここではその乱数について

  • そもそも乱数って何?
  • Unityで乱数を取得するには?

といった点について説明していきますね。

そもそも乱数とは?

まずはじめに、そもそも乱数とは何か?という点を簡単に説明しておきます。乱数とは簡単に言うと「でたらめな値」のことで、現実世界で言うと

  • サイコロを振って出た目の数
  • コインを投げた時の裏表

などが該当します。

ただし正確無比なコンピュータで本当にでたらめな値を出すのは困難なので、一般的にPC上では疑似乱数とよばれる「乱数っぽいもの」が用いられます。疑似乱数はあくまでも乱数もどきなので完全にランダムではなく、アルゴリズムによっては周期性があったり意図しない偏りが生じたりする場合があるようです。

しかしUnityに組み込まれている乱数生成機能はそこそこ性能が良いようで、普通のゲームを作るなら全く問題なく使うことができます。

Unityでランダムな値を取得する方法

では次にUnityでランダムな値を取得する方法を2通りご紹介します。

  1. 一様にランダムな値を取得する方法
  2. 偏りのあるランダムな値を取得する方法

それぞれ詳しく見ていきましょう。

一様にランダムな値を取得する方法

まずは一様にランダムな値を取得する方法です。この場合のやり方は次の2通りがあります。

  1. Random.valueを使う方法
  2. Random.Range関数を使う方法

Random.value

一つ目はUnityのRandomクラスにあるRandom.value変数を使う方法です。これを使うと、0.0~1.0までのランダムなfloat型の値を簡単に取得できます。

float randomValue = Random.value;

Random.Range関数

次に「2つの値を指定してその間のランダムな値を取得したい」という場合はRandom.Rangeという関数を使います。この関数の引数は次のようになっています。

Random.Range(最小値, 最大値)

引数にはfloat型かint型を指定できるのですが、float型を指定した場合は最大値が範囲に含まれるのに対して、int型を指定した場合は最大値が範囲に含まれないので注意してください(例えばRandom.Range(0, 3)とした場合は生成される値は「0, 1, 2」のいずれかです)。

このようになっているのは、配列のインデックスをランダムに取得するときに便利だからだと思われます。

Random.Range関数を使ったC#スクリプトの例

float型の乱数を取得するサンプルスクリプトは次の通り。

using UnityEngine;
using TMPro;

public class RandomSampleA : MonoBehaviour
{

    [SerializeField]
    float minValue = 0;
    [SerializeField]
    float maxValue = 100;
    [SerializeField]
    TextMeshProUGUI text;

    public void OnClick()
    {
        float randomValue = Random.Range(minValue, maxValue);

        UpdateText(randomValue);
    }

    public void UpdateText(float value)
    {
        text.SetText(value.ToString());
    }

}

下のGIFのように、ボタンをクリックすると予め指定した値(上記のスクリプトでは0~100)の間のランダムな値が表示されるという内容になっています。

乱数を取得した場合の例

(画像クリックでGIF再生)

偏りのあるランダムな値を取得する方法

お次は「ある程度はランダムにしたいけど、ランダムさに偏りを持たせたい」という場合のやり方です。これはUnity公式マニュアルにやり方がいくつか載っているのですが、個人的なオススメはアニメーションカーブを使う方法です。

アニメーションカーブはもともとアニメーションに使用するための曲線を作る機能なのですが、発想を変えると偏りのある乱数を生成するのにも便利です。横軸を乱数の値・縦軸を取得する値とみなすと、カーブの勾配が急なところは選択される確率が低く、逆に勾配が緩いところは選択される確率が高くなるため偏りのあるランダムな値となります。

アニメーションカーブの例

例えば上のようなアニメーションカーブの場合、最初と最後の勾配が緩いのでその部分の値が選択される確率が高くなる、といった感じですね。

ではサンプルスクリプトをご覧ください。

using UnityEngine;
using TMPro;

public class RandomSamleB : MonoBehaviour
{

    [SerializeField]
    AnimationCurve curve = new();
    [SerializeField]
    TextMeshProUGUI text;

    public void OnClick()
    {
        float randomValue = curve.Evaluate(Random.value);

        UpdateText(randomValue);
    }

    public void UpdateText(float value)
    {
        text.SetText(value.ToString());
    }

}

スクリプトは非常に簡単ですね。偏りのあるランダムな値を取得するためには、アニメーションカーブの値を取得するAnimationCurve.Evaluate関数の引数に乱数を渡すだけでOKです。

おわりに

以上、Unityでランダムな値を取得する方法について説明しました。やはり繰り返し遊べるゲームを作るためにはランダムな要素が欠かせないと思うので、ぜひ上記の内容を覚えて活用していただければと思います。

この記事がUnityでのゲーム開発のお役に立てば幸いです。