第10回 ループを使って効率化しよう (ForLoop 編)

前回は、下の画像のように初めて配列を使ってみました。
b10-1
ただし、あまり配列のありがたみは感じられませんでした。変数を複数個作った時とあまり変わらない手間がかかったのですから。今回は、配列の便利さを実感するために、どんなプログラミングでも非常に重要なループを紹介します。このループというのは、ある処理を繰り返し行うことなのですが、ブループリントにはループのためのノードが複数用意されています。まず、通常のループノードを使ってみましょう。
b10-2
b10-3
上の画像では、ForLoop というノードを使っています。全体のノードの数はいくつでしょうか?5個ですね。これは、前回のループを使っていない場合よりも 2 個減っています。配列のデータを取得するための Get ノードは 1 回しか使わないで済んでいます。「たった 2 個の節約か」と思われるかもしれませんが、もしも配列の要素が100個あって、それらをすべて表示する場合はどうでしょうか?それでもノードの数は変わりなく 5 個なのです。一方、ループを使わなければノードの数は、

Event Begin Play ノード 1 個+Greetings 配列ノード 1 個+(配列のデータを取得するための Get ノード 1 個+Print String ノード 1 個)×100=202個

にもなります。ちなみに第9回でやったように配列を使わない場合では (下の画像参照)、
b10-4
Event Begin Play ノード 1 個+(変数 1 個+Print String ノード 1 個)×100=201 個

になります。ループがなければ配列を使っても通常の変数を使ってもかなり大変です。

では、ForLoop はどのような働きをしているのでしょうか?あるいは、どのように使えばよいのでしょうか?先の画像をもう一度見てみましょう。
b10-5
まず、赤く丸く囲った実行ピンをたどって、全体の実行順から見てみます。ゲームが開始すると [イベント Begin Play] が発動します。つまり [イベント Begin Play] の実行ピンにつながっているノードが実行されていくことになります。ですから、[ForLoop] ノードが実行されます。[ForLoop] が実行されると、その実行ピン (Loop Body 実行ピン) につながっている [Print String] が繰り返し (ループなので) 実行されます。

Loop Body とは「ループ本体」という意味です。つまり、「ここにつながっている処理を、所定の回数繰り返し実行しますよ」ということなのです。言い換えれば、繰り返したい処理は、この Loop Body 実行ピンに接続させることになります。

では、First Index と Last Index とは何でしょうか?
b10-6
これは「ForLoop にあらかじめ Index という値が備わっており、その Index が First Index の横にある値から始まり、Last Index の横にある値になるまで、Loop Body につながっている処理を繰り返します。Index の値はループが 1 回完了すると 1 増加します」ということです。

たとえば、上の画像では First Index が 0 で、Last Index が 2 になっています。ですから、Index は 0 から始まります。Get ノードにこの Index の値 0 が供給されるようにしてある (ForLoop ノードの緑色の Index ピンから Get ノードの緑色のピンにワイヤーが伸びています) ので、Greetings という配列変数のうちインデックス 0 に入っている値 (Hello, World!!) が Get されます。そして Get ノードにつながっている Print String ノードが実行されて Hello, World!! が表示されます。これで 1 回目のループが完了します。ループが完了したので、ForLoop の Index は+1されます (そういう決まりになっています)。つまり、Index が 0+1=1 になります。

Index が 1 になると、当然、Get に渡される値も 1 になるので、Greetings 配列変数のうちインデックス 1 に入っている値 (Hello, UE4!!) が Get されます。そして表示されてループが完了し、Index は+1されて 2 になります。

Index が 2 になると、Get に渡される値も 2 になるため、配列変数 2 に入っている値 (Hello, Blueprint!!) が Get されます。そして表示されてループが完了しますが、Last Index が 2 だったので、これ以上ループは行われません。ここで実行はお終いです。なお、このようにループが完了した時に何らかの処理を行いたい場合は、Completed (完了した) 実行ピンにその処理を接続します。たとえば、下の画像では、ループが完了した時に「終わりましたよ!」と表示させています。
b10-8
b10-9

次回はもっと簡単に使える、配列特化型ループを紹介します。

最後に ForLoop に慣れるために、次の問題を考えてみましょう。

【振り返り問題】
インデックス (配列の要素番号) が 1 と 2 の配列要素を ForLoop を利用して表示するにはどうしたらよいでしょうか?つまり、Hello, UE4!! と Hello, Blueprint!! を表示しますが、インデックス 0 の配列要素に入っている Hello, World!! は表示しません。

【ノート】
Index の意味と役割
Index は「添字」という意味で、数学などでΣで下が i=1 などとなっている時に i に当たる数値のことをいいます。
b10-11
前回初めて登場した配列の「インデックス」もここから来ています(数学が嫌いな方は気にしないでください)。いずも繰り返しの処理が関係しています。ただし、同じ Index、インデックスでも別の意味 (使われ方) をもっています。Loop の Index は繰り返しの回数のカウントであり、配列のインデックスは、配列要素の何番目に入っているデータかを示しています。全然別の役割ですね (ただし、今回のブループリントではそれらを関係づけてみました)。ですから、ForLoop の Index は必ずしも配列のインデックスのためだけに使われるわけではなく、さまざまな使われ方をします。条件の一部になったり、計算の中に取り入れられたりさまざまです。そのあたりのことは次々回取り上げてみたい思います。

Get ノードへの値の供給について
本文中に、「Get ノードにこの Index の値 0 が供給されるようにしてある」とありますが、前回作ったグラフを振り返ると分かりやすいと思います。前回は下の画像のように、Get ノードで指定する値は小さなボックスの中に、0、1、2 というように手動で入れていました。
b10-7
それを今回は、ワイヤーで結び付けて、Index の値が Get ノードに直接供給されるようにしています。

コメントの付け方
先にあげたループを使ったグラフのように、
b10-12
「ForLoop を使って配列のデータを表示する」などのコメントを付けるには、そのグラフ全体を選択状態にして (左クリックしながら範囲指定します)、キーボードの C キーを押します。

プログラミングの方向性
プログラミングはブループリントに限らず、なるべく不要な重複を避けようとします。面倒だし、時間のムダになるからです。言い換えれば共通項をあぶり出して、似たような部分は 1 回で済ませようとしたいのです。今回のように、同じようなノードを何回も配置するのであれば、配列を利用しつつループにしてしまいます。(ただし、最初のうちは気にせずとにかくノードを使ってみて実験してみることのほうが大切かもしれません。)

通常の変数と配列の差
配列はループを上手く利用できますが、第8回で取り上げた Aisatu、Aisatu1、Aisatu2 などの通常の変数はループに上手くのせることができません。配列のようにインデックスがないためループの Index を上手く利用して、変数に入っているデータにアクセスできないためです。Aisatu1、Aisatu2 のように数字こそ付いていますが、これはあくまでも変数名の一部であって、インデックスとは違います。インデックスのような働きをさせることができないのです (配列のインデックスの働きは、配列に入っているデータにアクセスする時にその位置を指定することでしたね)。ですから、変数名に数字を付けたくなるような事態になったら、それらの変数は配列にしたほうが後々何かと便利になるかもしれないと考えてみるのがよいと思われます。

For の意味
ForLoop の For は、「~について」という意味です。もっと詳しく言うと、「値が変わる Index それぞれについて以下の処理を行います」となります。この意味を覚えておくと、ForLoop は使いやすくなるかもしれません。なお、他のプログラミング言語でも、この for ループは非常によく出てきます。



シェアする

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

フォローする