【Unity】乱数を使って空間に点やオブジェクトを描画してみる実験

Unityのマニュアルにある『ランダムなゲームプレイ要素の追加』を出発点とした乱数祭りもいよいよ終盤。
今回は『空間におけるランダムな点』の項目を使って、実際にオブジェクトをインスタンス化したり、画面に点を描画してみたいと思います。
環境
macOS 10.13 High Sierra
Unity2018.1.0f2
立方体の中のランダムな点を取得
3次元空間でランダムな位置を取得するなら、Vector3型でX, Y, Zそれぞれの値をRandom.valueにすればOK。
Random.valueは0から1までのfloat型の値を返してくれるので、ここに立方体の大きさを掛ければ拡大・縮小も簡単です。
オブジェクトの中心をベースにランダムな点を描画する場合は、-0.5fから0.5fに補正しておくとちょうどいいかも。
例として、Scaleが5の立方体の内部にオブジェクトがインスタンス化されるサンプルを作ってみます。以下のような立方体を目安として、実行時にメッシュを無効化してインスタンス化していきます。

Unityのマニュアルを参考にサンプルコードを作りました。
prefabはInspectorからアタッチできるようにしています。
上の画像で表示していた白い立方体の位置を目安にしているので、offsetも用意しています。
白い立方体の中心をベースとするため、Random.Rangeを使って+方向と-方向の両方に分布するようにしました。
このスクリプトを白い立方体にアタッチしてゲームを実行すると以下のようになります。(GIFは3倍速)

球体のランダム
オブジェクトを配置する範囲が球体の場合は、Random.insideUnitSphereを使うと便利。
半径が1の球体の内部にあるランダムな点をVector3型で返してくれます。
半径が1だとTransformのScaleは2に該当するので若干注意は必要ですが、こちらも簡単にランダムな値を取得できます。

以下のようなメソッドを追加して、球体の範囲内にオブジェクトをインスタンス化するようにしてみました。
上記のメソッドを追加して実行すると以下のようになります。

ランダムにオブジェクトを生成し、全体を埋めるような位置どりでした。
円のランダム
Unityのマニュアルでは球体ではなく平面の円の内部にある位置を返すRandom.insideUnitCircleも掲載されているのでそちらもサンプルを作ってみます。
上と同じように白一色ってのも寂しいので、プリンターのインク色を足してみました。

prefabのリストを保持するフィールドを用意し、Inspectorから上のインク色オブジェクトを追加します。
Random.insideUnitCircleではVector2型が返されるので、それを使うとX-Y平面状にオブジェクトを配置することができます。
メソッドを追加したらスクリプトを保存してゲームを実行します。

X-Y平面の円の範囲内にオブジェクトがインスタンス化されました。
時間経過でシアン(水色)の割合が増えているように見えますが、これは乱数の偏りではなく、描画順の問題のようです。
試しにPrefabとして使用したオブジェクトを重ねてみると、以下のようになります。

3種類のオブジェクトに関して領域が重なるように配置すると、シアン(水色) > イエロー(黄色) > マゼンタ(ピンク)の順番になっていることから、Prefabのインスタンス化を行う際も同じように手前に描画されたようです。
手前に来るオブジェクトが増えれば、その分全体的にシアン(水色)が多いように見えてしまいますね。
どの順番で描画されるかはMaterialの話になってくるのでここでは深く突っ込まないようにします。うん、それがいい。
どのケースも偏りはなさそう
それぞれのGIF動画を眺めてみても、ある領域だけ全然オブジェクトが生成されないといった極端な乱数の偏りはなさそうですね。
Random.insideUnitSphereもRandom.insideUnitCircleも、内部的には多分同じアルゴリズムで、乱数を取る範囲だけ違うんだろーなーと予想。
そのうち乱数の性能も確認してみたいです。
今回でUnityのマニュアルに載っている範囲を制覇できたので、あとは別の資料を使って乱数への理解を深めるだけ。
乱数の世界は結構沼いですが、ゲームでは乱数が欠かせないし極めたいなーと。
乱数の状態保存とかシードの話もやってないので、次回以降はその辺りも触れていきたいです。
ゲーム開発の攻略チャートを作りました!
-
前の記事
【Unity】山札からトランプの手札を配るサンプル2通り 2018.06.26
-
次の記事
Unityでゲームを作ってるので乱数について勉強を始めてみたよ 2018.06.28
コメントを書く