ゲームと乱数
ゲームにはほぼ必ず乱数が介入します。
つまりランダムな運による要素です。
双六ではサイコロを振り、人生ゲームではルーレットを回すでしょう。
デジタルなゲームでもRPGのドロップアイテム、敵とのエンカウント、回避の判定、
などをはじめとして枚挙に暇がありません。
乱数はゲームの結果を一定にせず、面白くするために必須の要素だと思います。
Unityと乱数
Unityには乱数を生成するクラスがあります。
以下の例の場合、0から99までの範囲でランダムな整数を返します。
using UnityEngine;
private void Awake()
{
int random = Random.Range(0, 100);
}
float型のメソッドもあります。
System
名前空間に、System.Random
というクラスも存在しますが、
今回はUnityEngine
名前空間のUnityEngine.Random
の説明をしています。
シード値とは?
乱数を生成する機能を乱数生成器と言いますが、基本的な完全なら乱数では無く疑似乱数生成器です。
つまり、ランダムに見えて実は周期性と再現性を持っています。
周期性を感じさせないようにする、また再現性を持たせるために使用するのがシード(種)値です。
以下の例では、シード値を0としてるので、ログには毎回同じ値が出力されます。
using UnityEngine;
using Random = UnityEngine.Random;
private void Awake()
{
Random.InitState(0);
Debug.Log(Random.Range(0, 100));
}
できるだけランダムにするには現在時刻のミリ秒をシード値にするとよいかもしれません。
using System;
using UnityEngine;
using Random = UnityEngine.Random;
private void Awake()
{
Random.InitState(DateTime.Now.Millisecond);
Debug.Log(Random.Range(0, 100));
}
Minecraft
というゲームにもシード値というものがありますが、これがワールドの生成ロジックに使用されているため、
通常ランダムに生成されるワールドもシード値を同じにするとこと他人と同じワールドを生成して遊ぶことが出来ます。
インスタンスを作りたい
Unity.Random
は別のインスタンスを作ることが出来ませんので、ゲーム中必ず単一の乱数生成器を使うことになります。
需要があるか分かりませんが、乱数生成器を分けたい場合には、Mathematics
パッケージを使います。
使用するバージョン
- Mathematics 1.2.6
Package ManagerからMathematicsをインストールする
PackagerManager
を開いて、Mathematics
を探して、Install
ボタンを押します。
乱数生成器を生成する
using System;
using UnityEngine;
private void Awake()
{
var random = new Unity.Mathematics.Random((uint)DateTime.Now.Millisecond);
Debug.Log(random.NextInt());
}
Unity.Mathematics.Random
にシード値を与えると複数の乱数生成器を作ることが出来ます。
Unity.Random
クラスと違い、シード値はuint
型になります。
Next〜
系のメソッドはint
,float
以外にも沢山用意されています。
似たような乱数が出力される
先ほどのコードで乱数を出力してみると似たような値が出力されました。
シード値が近いとこのようになる特性があるようです。
その場合、CreateFromIndex
メソッドを使って乱数生成器を作るといいかもしれません。
引数を元にメソッド内でハッシュ値を計算してそれをシード値としてくるようです。
using System;
using UnityEngine;
private void Awake()
{
var random = Unity.Mathematics.Random.CreateFromIndex((uint)DateTime.Now.Millisecond);
Debug.Log(random.NextInt());
}
規則性を感じられなくなりました。
まとめ
- 乱数を必要なら、
UnityEngine.Random
が使える。 - シード値で乱数は再現できる
- 不具合を再現したい場合に固定のシード値を使えるようにするとデバッグに役立つかもしれません。
- 複数の乱数生成器が必要なら、
Mathematics
パッケージを使おう。