【UEFN】Random Number Generatorの使い方|Verse配列制御による乱数実装と比較
こんにちは、UEクリエイターズです。今回もUEFN(Unreal Editor for Fortnite)の使い方について解説していきます。
この記事では、Random Number Generator Device(ランダムナンバージェネレーターの仕掛け)とVerseを使ったランダム処理の実装比較について具体的に説明していきます。
動画でも解説しているので参考にしてみてください。
概要(何ができるか)

ゲーム制作において「ランダムにアイテムを排出する」「ランダムな位置にライトを点灯させる」といったランダム要素(乱数処理)は頻繁に使用されます。
UEFNでは、既存のRandom Number Generator(ランダムナンバージェネレーター)の仕掛けを使用する方法と、Verse言語で記述する方法の2パターンが存在します。
本記事では、以下のシンプルなゲームロジックを例に、両者の実装方法とメリット・デメリットを比較解説します。
- 要件: ボタンを押すと、4つのライトのうち1つだけがランダムに点灯する。
- 結論: 拡張性や管理コストを考慮すると、Verseでの実装が圧倒的に推奨されます。
仕掛け(Device)のみでの実装方法と課題

まずはVerseを使わず、仕掛けだけで実装する場合の手順です。
必要なデバイス


- Random Number Generator (ランダムナンバージェネレーター) × 1
- Trigger (トリガー) × 4(制御対象の数だけ必要)
- Customizable Light (カスタマイズ可能なライト) × 4
- Button (ボタン) × 1
設定手順
1.Random Number Generatorの設定

Value Limit 2 (値の制限 2):4 に設定(1〜4の乱数を生成するため)。

Zone Direction (ゾーンの方向):Forward (前) に設定。物理的な検知ゾーンを作成します。
2.Triggerの配置

生成されたゾーン内に、物理的な位置関係を利用して4つのトリガーを並べます。
これにより、乱数の結果(1〜4)に応じて、手前から奥のトリガーが起動する「物理的な配列」を構築します。
3.イベントの紐づけ

各Triggerが起動した際、対応するCustomizable Lightが Turn On (点灯) するよう個別に設定します。
Buttonを押した際、全てのライトがリセットされる処理も個別に設定が必要です。
この手法の課題(スパゲッティ問題)
仕掛けのみの実装はノーコードで可能ですが、以下の致命的なデメリットがあります。
- 拡張性が低い: ライトを4個から20個に増やす場合、トリガーの複製、物理配置の調整、イベント紐づけ作業が膨大になります。
- 管理が複雑: どのトリガーがどのライトに対応しているかが視覚的に分かりづらく、いわゆる「配線のスパゲッティ化」のような状態になりがちです。
Verseによる制御・実装

Verseを使用すれば、物理的な仕掛けの配置に依存せず、配列(Array)と乱数関数を使用してシンプルかつ拡張性の高いロジックを構築できます。
必要なデバイス

- Customizable Light (カスタマイズ可能なライト) × 4(または必要な数だけ)
- Button (ボタン) × 1
- Verse Device × 1
Verseコードの作成
以下は、動画内で解説されているVerseコードの全容です。
GetRandomInt 関数を使用するために Random モジュールをインポートしている点に注目してください。
コード スニペット
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /Verse.org/Random } # ランダム機能(GetRandomInt)を使うために必要です
# ランダムにライトを点灯させるデバイス
random_light_manager := class(creative_device):
# ライトを配列(リスト)で登録します
# エディタ上で + を押してライトを何個でも追加できます
@editable
MyLights : []customizable_light_device = array{}
# 起動用のボタン
@editable
Button : button_device = button_device{}
# ゲーム開始時の処理
OnBegin<override>()<suspends>:void=
# ボタンが押されたら OnButtonPushed を実行するよう設定
Button.InteractedWithEvent.Subscribe(OnButtonPushed)
# ボタンが押された時の処理
OnButtonPushed(Agent:agent):void=
# 安全装置:ライトが1つも登録されていないとエラーになるのでチェックします
if (MyLights.Length > 0):
# 1. まず全てのライトを消灯(リセット)します
# これをしないと、ボタンを押すたびに点灯するライトが増えていってしまいます
for (Light : MyLights):
Light.TurnOff()
# 2. ランダムな数字(インデックス)を決定します
# 最小値 0, 最大値 (ライトの数 - 1) の間で計算します
RandomIndex := GetRandomInt(0, MyLights.Length - 1)
# 3. 決まった数字を使って配列からライトを取り出し、点灯させます
# 配列へのアクセス(MyLights[...])は失敗する可能性があるので if を使います
if (SelectedLight := MyLights[RandomIndex]):
SelectedLight.TurnOn()
Print("ライト番号 {RandomIndex} を点灯しました")
実装のポイント解説
配列(Array)による管理
@editable
MyLights : []customizable_light_device = array{}
と記述することで、エディタ上でライトをリストとして管理できます。これにより、対象が4個でも100個でも、コードを書き換えることなくエディタ上で要素を追加するだけで対応可能です。
GetRandomInt の活用
RandomIndex := GetRandomInt(0, MyLights.Length - 1)
GetRandomInt(Min, Max) は、指定した範囲の整数をランダムに返します。配列のインデックスは 0 から始まるため、最大値には MyLights.Length – 1(配列の要素数マイナス1)を指定することで、配列外参照のエラーを防ぎつつ、完全なランダム選択を実現しています。
状態のリセット
for (Light : MyLights):
Light.TurnOff()
の部分で、処理の最初に全ライトを消灯しています。これにより、常に「1つだけ点灯している」状態を保証できます。仕掛けでこれを行う場合、全てのライトに対して個別にリセットイベントを設定する必要があり非常に手間ですが、Verseなら数行で完結します。
まとめ
今回の検証から、ランダム要素を含むゲームロジックの実装におけるVerseの優位性が明確になりました。
| 項目 | 仕掛け(RNG Device) | Verse実装 |
| 必要なデバイス数 | 多い(RNG + トリガー複数) | 少ない(Verseデバイスのみ) |
| 拡張性 | 低い(複製と再設定が手間) | 高い(配列に追加するだけ) |
| 管理のしやすさ | 複雑(物理配置と紐づけ) | シンプル(コードと配列) |
| 処理負荷 | デバイス数に比例して増加 | 軽量 |
特に「対象の数が増減する可能性がある」場合は、迷わずVerseを選択することをお勧めします。開発効率だけでなく、レベル上の見た目もスッキリとし、バグの温床となる複雑な紐づけを回避することができます。
ぜひ、今回のコードをコピーして、ご自身のプロジェクトで活用してみてください。
関連資料
動画版の視聴はこちらから:https://youtu.be/gy11RfD8XTk


