PaperSloth’s diary

主にゲーム開発関連についての記事を書きます。

UE4 Blueprintで使える便利なフロー制御のノードについて

環境

UE4.26.0

概要

Blueprintにはデフォルトで用意されているノードにFlipflop, Gate, DoN, MultiGate等の便利なノードがあります。
C++で同じような処理を組む際には面倒なものでも、こういったノードを上手く使えば簡潔に処理を書くことができます。
今回紹介するのは以下のノードです。
f:id:PaperSloth:20210113232832p:plain

Flipflop

f:id:PaperSloth:20210113175149p:plain
実行される度にA, Bの処理を交互に実行する。
簡単な例でいうとドアの開閉処理や、ボタン操作等が分かりやすいかもしれません。

例で組んだノードではEnterキーを押下する度に「Open」と「Close」のログが出力されます。
f:id:PaperSloth:20210113173608p:plain

最初にEnterキーを押下した場合には「Open」が出力され
次にEnterキーを押下した場合には「Close」が出力されます。
さらにもう一度Enterキーを押下した場合には「Open」が出力されます。

こういったようにFlipflopノードに繋いだ処理をAの出力とBの出力が交互に実行されるわけです。
例えば、デバッグ用に録画開始ボタンと録画終了ボタンを設定しておくなどの使い方もできます。
f:id:PaperSloth:20210113174217p:plain

この方法で撮影した動画はProjectのDirectoryの Saved/VideoCapture/(ProjectName).avi の形式で保存されます。

Flipflopを使用せずに同じ処理を組もうとした場合には以下のような組み方になります(IsCaptureのdefault値はfalse)
Flipflopを使用した場合と異なるのはbooleanの変数を1つ追加する必要があることですね。
極力Blueprintを複雑にしないためにも、削減可能な変数は削減したいところです。
f:id:PaperSloth:20210113174615p:plain

Gate

f:id:PaperSloth:20210113175308p:plain
Enter : GateがOpen状態なら処理が実行される
Open : GateをOpen状態にする(Enterに処理が来た時に処理が実行される状態になる)
Close : GateをClose状態にする(Enterに処理が来た時にClose状態では処理が実行されない)
Toggle : Open <-> Close状態を切り替える
Start Closed : デフォルトのGateの状態をClose状態にするかどうかのフラグ

ちょっぴり複雑なノードが出てきました。
挙動としては上記に書いたように、Enterに処理が来た時にOpen状態ならExitに繋いだ処理が実行され、Close状態なら処理が実行されないといったシンプルなものになります。
Gate(入り口、門)という名前の通りで門が開いている時には処理が行われ、閉じている時には処理が行わないというものです。


例 : 右クリックを押下している時だけ回転するカメラの実装
今回の使用例では右クリックを押下している時にだけしか回転しないカメラを実装しました。
f:id:PaperSloth:20210113214123p:plain

MouseXノードはMouseを動かしている時、そうでない時に関わらず前フレームからのマウスの横方向への移動量を返します。
Tickのように毎フレーム処理される入力ノードです。
そこにGateを組み合わせて右クリックを押した時に開いて離すと閉じるようにしています。
こうすることで、右クリックを押している時だけ、AddControllerYawInput(カメラの左右方向の回転)が呼び出されます。

GateはTimelineやTickと組み合わせることが多いかと思います。
一定のボリュームの中でだけ動作する機能や、一定の入力を行っている時だけ動作する機能などを簡単に実装することができます。

DoN

f:id:PaperSloth:20210113205010p:plain
Enter : Nに設定した回数が残っていればExitに繋いだ処理が実行される
N : 実行可能な最大数
Reset : Nで指定した値でCounterをリセットする
Exit : 実行したい処理を繋ぐ
Counter : 実行された回数(1,2,3と増えていくため実行可能な残り回数ではない)
     また、Resetした際にCounterもResetされます。

一定回数だけ実行可能な機能を作成したい場合に使用するノードです。
勘違いしがちなのは、DoNでNに指定した回数連続で処理が実行されると思うかもしれませんが
そういった機能ではありません。

回数制限を加えた処理を作成したい時などに使えるノードになっています。
例1. 一定回数だけ取得が可能なイベント(某ランゲームのコインが取得可能なブロックのイメージ)
例2. 一定回数攻撃を加えることで破壊可能なオブジェクトの破壊処理
f:id:PaperSloth:20210113230737p:plain

MultiGate

f:id:PaperSloth:20210113205025p:plain
入力 : デフォルトでは、入力は順番に機能し、すべての出力が終了すると、機能は実行されません。
Reset : StartIndexで指定した数値に初期化されます。
Is Random : 出力をランダムに実行します。
      Loopのフラグが立っていない場合は、すべて実行すると機能しなくなります。
Loop : 全ての実行が終了した後も再度実行可能になります。
Start Index : 関数の最初の出力を示すIndex。-1の場合でLoopが立っていない場合は上から順次実行します。

例:カメラを3つ順次切り替えたい場合
まずはLevel上に下図のように3つカメラを配置します。
f:id:PaperSloth:20210116163146p:plain

スクショで1画面に収める都合でノードの繋ぎ方が汚いですが
以下のようにMultiGateを使用してLoopにチェックを入れることでカメラ1 -> 2 -> 3 -> 1 ...と切り替えることができます。
f:id:PaperSloth:20210116163615p:plain
f:id:PaperSloth:20210116163809g:plain

Loopフラグを使わない場合でも以下のように最後の処理が実行された後にResetに繋ぐことでLoopを組むこともできます。
挙動としては先程と同様です。
f:id:PaperSloth:20210116163921p:plain

Randomにチェックを入れた場合には以下のような挙動になります。
ただし、Randomの実行結果としてOut0 -> Out0のように同じ出力を行うケースも存在するため
使用する際にはその点に留意してお使いください。
f:id:PaperSloth:20210116164229g:plain

まとめ

上記で説明した以外にBlueprintには便利なノードが数多く存在します。
今回の例でいうとGateやMultiGate等はC++で組むとなるとちょっと面倒くさいです。
Flipflopに関してはC++でも楽ですが。
また、Blueprintでの利点としてはMultiGate等のように出力数を簡単に増減できるところも魅力的ですね。
既存のノードを頭の片隅に入れておいてより読みやすいノードの流れが組んでいけるといいですね。

以上です。