BLOGブログ

2018.05.11UE4/Blueprint

[UE4] フレームをまたいで配列を反復するマクロの作り方

先々週の記事でマクロのローカル変数の保持とワイルドカードについての話題があったので、今回はそれらの機能を活用したフレームをまたいで配列を反復するマクロの作り方を紹介したいと思います。

まずはフレームをまたいで配列を反復するとはどういうことか、そこから説明したいと思います。普段、皆さんが利用している配列の反復方法はおそらくForEachLoopかと思います。

 
LoopBodyの実行ピンをつなげる事で、InputのArrayの中身を上から順に取得でき、最後にCompletedの実行ピンの処理が走るマクロですね。この時、LoopBodyは1フレーム内で処理が走ります。では、配列の中身を1秒おきに表示したい場合どうするのか。


このようにノードを組んでも意図通りには実行されません。LoopBody以降にDelayノードをつなげても、ForEachLoopのループ内の処理がそこで一時停止するわけではなく、次のインデックスのLoopBodyが即座に実行されます。まあ、当然といえば当然ですね。
ちなみにDelay後にさらにノードを繋げていた場合、最後のインデックスの内容が1秒後に一度だけ実行される事になります。

 
この例のように配列を上から順に指定秒置きにアクセスするという事はあまりないかもしれませんが、たとえばこれがDelayノードではなく、別のLatentノードであればどうでしょう?
たとえばアセット型の配列を作成し、上から順にAsyncLoadAssetで読み込みを行いたい場合などが該当するかと思います。


そんな時に、フレームをまたいで配列を反復するマクロが必要になってくるわけですが、今回はそれを作ってみたいと思います。

基本的な構成はForEachLoopと同じにします。ただし、LoopBodyが完了して次のLoopBodyを走らせるタイミングをマクロに教えてあげる必要があるので、Inputに実行ピンを1つ増やす事にします。

マクロ内は以下の形になると思います。ご覧の通り、とくに難しい処理をしているわけではありません。マクロ内でローカル変数である、LoopCountとArrayIndexを用意し、ワイルドカードの配列を0から順にアクセスしています。ForEachLoopと違う点として、任意のタイミングになるようにNextの実行ピンによって配列のインデックスがインクリメントされています。

実際にこのマクロを使用して、アセット型の配列を順番に読み込んでみたいと思います。

さて、このマクロですが使用時に注意が必要です。
普段、ForEachLoopWithBreakを使う際にBreak時にイベントを使用している方もいるかと思います。

これと同じように今回のマクロでもNextの実行ピンにイベントを使用した場合、ノードの配置がきれいになります。

しかしこれはよく見るとカスタムイベントが再帰的に呼ばれていますね。ですが上記の場合はまだ問題はありません。しかし以下のように組んだ場合にどうでしょう。

LoopBodyとNextの間が同フレームだった場合、ブループリントのコールスタックが溜まってきいき、124回目のループで無限ループと判断されてアプリケーションが停止してしまうので注意が必要です。

とまぁ注意点はありますが、このようにマクロは工夫一つで様々な事が便利に使いやすく実装する事が可能です。皆さんも既存のマクロを参考にしながら色々と便利なマクロを用意して、スムーズなゲーム開発を目指しましょう!