ブループリント クイックショット⑫ Random Streams

ビデオの内容紹介
アクタをレベルに配置する時に、ランダムな値を使って位置を決めます。ただし、そのランダムの値の取り方によっては、より配置しやすくなる場合があります。

原題 Unreal Engine 4 Blueprint QuickShot – 12 – Random Streams

作るもの①
アクタを配置する際に、その位置がランダムで変わるようにします。

完成図①
1201

実行結果①
1202
1203
Details パネルで Default の NumBushes (低木の数) を 5 から 7 に変えると、その配置場所もガラリと変わります。

作成上の注意点①
① まずコンテンツ ブラウザの New をクリック → Blueprint → 名前を BushSpawner にします。
② BushSpawner をダブルクリックしてブループリントを開いたら、Details の Static Mesh セクションで SM_Bush を選択します。
③ 変数 NumBushes は、Int (整数) 型です。後からエディタで変更できるようにするために、目のアイコンをクリックして Editable (編集可能) にします。さらに、左上 Compile をクリックして、Default Value を表示して、そこを 5 にします。
④ ForLoop の First Index を 1 にします。

グラフの意味①
Construction Script はこれまでにも何回も出てきました。このノードのポイントは、Construction Scriptを含むアクタがレベルに配置されたり改変(更新)された場合に、このノードにつながっている関数などが実行されるということです。

この例の場合は、後でコンテンツ ブラウザからこのブループリントをレベルにドラッグアンドドロップするので、その時にこの Construction Script が発動することになります。(さらにエディタの Details で [編集可能に設定しておいた] 変数 NumBushes を変更することによっても、Construction Script が発動します。)

Construction Script が発動すると、ForLoop が発動します。これは、1 (First Index) から Last Index まで Loop Body に接続しているものを繰り返します。Last Index には NumBushes (低木の数) が接続しており、この変数の値は 5 なので、ForLoop は 1 から 5 まで (つまり 5 回) 繰り返されることになります。(なお蛇足ながら、30 から 34 にしても結果は同じになります。5 回なので。)

LoopBody には、AddStaticMeshComponent (メッシュのコンポーネントを追加する) がつながっています。つまりメッシュをレベルに追加するのですが、Details で設定した SM_Bush を追加します。スポーンする位置は Relative Transform (相対的トランスフォーム) に供給されます。

その位置は、まず、Random Float in Range (ある範囲内にある float 値をランダムで生成する) でランダムな浮動小数点型の値が作られ、それを Make Vector でベクタにしています。範囲は、-200 ~ 200 です。Z の値はゼロのままにしているので、追加する低木の上下の位置は変わりません。

出来上がったベクタは、Make Transform によって位置情報にされて、AddStaticMeshComponent の Relative Transform に供給されます。

まとめると、ランダムな値によってメッシュの位置を決めてレベル内にスポーンさせるグラフです。

作るもの②
アクタを配置する際に、その位置をランダムに決定しますが、アクタの数を増やしても、すでに置かれているアクタの配置は変わらないようにします。

完成図②
1204

実行結果②
1205
1206
1207
1208
低木の数を 5 から 8 まで増やしています。増やした時に、それまでの位置に変化はありません。これが結果図①との大きな違いです。

作成上の注意点②
完成図①と異なる点は、Random Float in Range の代わりに Random Float in Range from Stream を使っている点です。

Random Float in Range from Stream には、ランダムな値の源である Rand Stream 型 (構造体) の変数である RandStream で、ランダムな数を供給しています。RandStream 変数は、Details の Variable Type (変数の型) で、Structure (構造体) → Random Stream を選択します。

グラフの意味②

この Random Float in Range from Stream は、「ストリームによって、ある範囲内にある float 値をランダムで生成する」という関数です。

より詳しく言うと、ランダム関数というのはどんな言語であっても純粋にランダムなものは作れず (その方法がありません)、計算で擬似的な乱数を求めています (一見ランダムに見える値を作ります)。その時、計算式に使う値をシード (seed、種) と言います。

たとえば、円周率を求める計算式を擬似乱数を作る式だとします。そしてその式にシードを入れると、そのシードの値が、乱数開始が少数第何位からかを指すように機能するとします。たとえば、シードを 1 と指定すると乱数は 14159… となり、シードを 2 とすると乱数は 4159… というように (円周率は、3.14159…です)。

このように特定のシードを指定すると、必ず特定の値から始まります。「乱数はランダム」という印象からはだいぶ外れます。これが擬似乱数の本当の姿です。円周率計算式でなくても本質は同じです。

実行結果②が①と異なるのは、実行結果②の Random Float in Range from Stream のシードが一定であるため、それを利用するメッシュの位置が一定になるわけです。Random Float in Range の方は、そのような機能がありません。

なお、Random Float in Range from Stream でシードを Details で変更すると、もちろん配置もガラリと変わります。

少しややこしい話なので、うまく説明できたか若干不安が残りますが、次の実験を理解の助けにしていただければと思います。

実験
1209
これは MyCharacter ブループリントに入れ込んだグラフです。

動作は非常に単純で、F キーを押すと Random Float in Range が 2 回発動し、G キーを押すと Random Float in Range from Stream が 2 回発動して、得られた擬似乱数を表示するというものです。

次のスクリーンショットは、その結果です。まず Play を押して、 F と G を押して擬似乱数を表示してから、Play から抜け出ます。そして、再度 Play を押して同様のことをします。
1210
1211
1 枚のスクリーンショット内の上 2 つが G つまり Random Float in Range from Stream で得られた乱数です。2 枚のスクリーンショットを比較すると値が変わっていないことが分かります。一方、1 枚のスクリーンショット内で下の 2 つは F キー即ち Random Float in Range で得られた乱数ですが、こちらは Play し直しても値が変わっています。予想どおりでした。

今回はこれにて終了です。どうもお疲れ様でした!



シェアする

  • このエントリーをはてなブックマークに追加

フォローする