🙄

【UE4/UE5】ブループリントでアイテムドロップ率とかに使う重み付き抽選を行う

2022/03/27に公開

重み付け(アイテムドロップ率とかに使うやつ)

抽選率は合計100%とかにしなくても問題なし

10%,40%,50%とかの計100%にしなくても大丈夫です。
10%,20%,22%とか、計100%に達していなくても抽選されます。

実装例

一番上に貼ってある画像と見比べながら実装していただけたらと思います。

1.構造体を作る

まず、構造体を作ります。
構造体の中身は、アイテム情報(独自クラス)とアイテムの抽選率(float型)が入ってます。
※画像中の"Item And Rate"

構造体は、アイテム名(string)と抽選率(float型) とか、 アイテムID(int)と抽選率(float型) とかの方がわかりやすいので、自分好みの構造体を作っていただけたらと思います。

2.構造体の配列を用意する

先ほど作った構造体の変数を作ってしまいます。変数を作成する際、詳細タブで配列に変更します。
作ったら配列の初期値を以下のような感じで設定していきます。

3.抽選用の関数を用意&関数内にローカル変数を2つ用意

関数を用意したら以下のようにローカル変数を用意します。

初期値は0で大丈夫です。

L_TotalRate
アイテムの抽選率を足した合計値として使う

L_RandomPoint
0~合計値の間のランダムな数値として使う

4.L_TotalRateに合計値を入れる

1つめのfor each loop でアイテムの抽選率をどんどん足していきます。
その際に、構造体を分解し、抽選率の部分を取り出します。

5.L_RandomPointに値を設定

1つめのfor each loop が終わったタイミングで、”Random Float”(0~1の数値をランダムで取得)と ”L_TotalRate” をかけます。かけた数値を L_RandomPoint に設定します。

こうすることで、0~抽選率の合計値(例:0.9 + 0.2 + 0.7 = 1.8)の間の数値をランダムに取得することができます。

実際に、抽選率の合計値( 1.8 ) に1をかけると1.8ですし、0.2をかけると0.36(1.8の20%の値)になります。

6.抽選する

再びループを回し、アイテムの抽選率より L_RandomPoint の値が小さいなら、そのアイテムが当選したことになります。

L_RandomPoint の値が大きい場合は L_RandomPoint からアイテムの抽選率を引いていきます。こうすることで次のループで当選する確率を上げます。

当選したらすぐにループを抜けるように、当選した値を関数の出力に設定します。

これで一通りの実装が終わりました。

コピペ用

参考記事(重み付きって何?って時に参考になるかも)

こちらの記事の参考にさせていただきました。
https://ekulabo.com/random-with-weight

Discussion