LoginSignup
4
1

More than 1 year has passed since last update.

Unityで予測できるランダム値を生成

Last updated at Posted at 2021-12-15

PONOS Advent Calendar 2021の16日目の記事です。

昨日は@714hoさんの「Unityログにタグをつけて見やすくする方法」でした!

はじめに

※間違いや不自然な日本語があったらスミマセン。

次の記事を参考にしたものです(英語):https://blog.redbluegames.com/generating-predictable-random-numbers-in-unity-c97b7c4895ec

UnityEngine.Randomを使うか?System.Randomを使うか?は考えたことないですか?

予測できるランダム値を生成したい場合は、UnityEngine.Randomは使いにくいです。
UnityEngine.Randomはstaticであり、共通で使われるものなので、他のプラグインやコードに呼ばれる、又は初期化される可能性があります。

以下のように設定すれば、自分で制御できます:

public static class RandomUtils
{
    public static System.Random RNGSingleton = new System.Random();
}

たとえば、確率で何かを行われる場合は以下のメソッドが使えます:

public static bool RandomChance(System.Random rng, int percent)
{
    return rng.Next(0, 100) < percent;
}

もう一つの例です。こちらはレンジの中でランダムな値を返します:

public static bool RandomRange(System.Random rng, int min, int maxExclusive)
{
    return rng.Next(min, maxExclusive);
}

普段はRNGSingletonをパラメータとしてパスします。

予測できる値を生成する

たとえば、宇宙の中で遊べるゲームを作っています。
「銀河」をいくつか生成して、それぞれはさまざまな「惑星」を生成します。
この場合はまずシードを設定して、次にランダムを初期化します:

// シードを設定
int seed = RandomUtils.RandomRange(RandomUtils.RNGSingleton, 0, int.MaxValue);

// ランダムを初期化
var random = new System.Random(seed);

// それぞれの銀河が同じランダムにより生成
foreach(var galaxy in galaxies)
{
    galaxy.Generate(random);
}

「銀河」はまた「惑星」に「random」をパスするイメージです。

例:

// galaxy = 銀河
public class Galaxy
{
    // 生成メソッド
    public void Generate(System.Random random)
    {
        // 50%の確率で…
        if (RandomUtils.RandomChance(random, 50))
        {
            // 大きな惑星を追加
            var planet = new BigPlanet();
            planet.Generate(random);
        }
        else
        {
            // 小さな惑星を追加
            var planet = new SmallPlanet();
            planet.Generate(random);
        }
    }
}

こうやって、シードを保存すれば毎回同じ宇宙を生成できます。


明日は@nisei275さんです!

4
1
0

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
4
1