［UE5］スタッフロールのような、複数のウィジェットがつながってスクロールするウィジェットを作る

# 概要
この記事では、Unreal Engine 5 で、下の動画のような、複数のウィジェットをつなげて、下からスクロールさせることができるウィジェットを実装します。
ゲームである、スタッフロールのようなものです。

<iframe width="640" height="360" src="https://www.youtube.com/embed/6D-0u3ihDZQ" title="scroll widgets 1" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>


# この記事の主な対象者
- Widget Blueprint（WBP）の作り方の基礎を習得されている、初心者の方



# 1. スクロールさせるウィジェットの元として使用するウィジェットを作成する

スクロールさせるウィジェットを簡単に量産できるようにするために、最初にスクロールさせるウィジェットの元とするウィジェットを作成していきます。

下図のようなウィジェットの構成のWBPを作成します。（今回の記事では、作成するウィジェットのWBPの名前を「WBP_ScrollWidget」にします。）

![scrollwidget_widgets.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/f4d2927f-f95f-c4bf-859a-3e9c38c1c09a.jpeg)

|ウィジェット名|ウィジェットの種類|備考|
|:-:|:-:|:--|
| Canvas Panel | Canvas Panel | このウィジェットを一番上の親にします。 |
| ScrollPanel | Named Slot | スクロールで表示する画面を、ほかのウィジェット上で設定できるようにするために使用します。 |

上のウィジェット構成のWBPを作成したら、「ScrollPanel」ウィジェットの詳細パネルを開きます。詳細パネルの「スロット」＞「サイズX」「サイズY」（下図の赤枠）には、親の「Canvas Panel」ウィジェットのサイズを設定し、「スロット」＞「Alignment」＞「Y」（下図の緑枠）には、「-1」を設定します。

![scrollpanel_slot.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/a087faf2-7d1f-648d-75c4-ccb9ad1fcd97.jpeg)

上図の設定が終わったら、エディタ上でウィジェットが下図のように表示されているかを確認します。

![scrollwidget_designer.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/0a580169-7dab-87e2-4f90-7ab4cbb45abf.jpeg)

これで「ScrollPanel」ウィジェットの初期位置を、画面下に設定することができています。<br><br>


上図のようになっていることが確認できたら、次は、画面下にある「ScrollPanel」ウィジェットを、画面上まで移動させるアニメーションを作成します。

下図のようなアニメーションを作成します。（今回の記事では、アニメーションの長さを4秒にするとともに、アニメーション名を「Scroll」にします。）

![scrollanimation.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/28096492-ed51-0861-a9f4-6efa780da00d.jpeg)

上図の赤丸（4.00秒）における「Alignment Y」の値には「1」、上図の緑丸（0.00秒）における「Alignment Y」の値には「-1」を設定します。

上図の赤丸と緑丸の点を右クリックし、「リニア」にチェックを入れるようにして、スクロールするウィジェットの移動が線形移動になるようにします。

![linear.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/cc71dbe8-c39c-e3bf-eb78-bbe6af742072.jpeg)


また、上図のアニメーションタイムラインの、オレンジ丸におけるキーは、アニメーションの長さの半分である2.00秒に設定します。

「なぜ上図のオレンジ丸のところに、イベントを呼び出すキーを追加したのだろうか？」とお思いになる方がいらっしゃると思うので、上図のオレンジ丸のところに、イベントを呼び出すキーを設定した理由をご説明します。
ゲームプレイ中に、上図のオレンジ丸のところが再生されているときは、ゲームプレイ画面は下図のような状態になります。

![scroll_exp2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/61c2aad7-3c12-ee40-e524-dc894423f0c8.jpeg)

そのため、上図のアニメーションタイムラインのオレンジ丸のところで、画面外に出て表示する必要がなくなった上図の「ウィジェット1」を非表示にする処理と、今から画面に映り始める必要のある上図の「ウィジェット3」をスクロールし始める処理を呼ぶ必要があります。

なので、アニメーションの半分の長さであるオレンジ丸のところに、イベントを呼び出すキーを設定しました。<br><br>

オレンジ丸のイベントを呼び出すキーのイベントの中身を実装していきたいのですが、実装するためには先に、スクロールさせる複数のウィジェットを管理するウィジェットを作成する必要があるため、そちらのウィジェットの作成が終わった後に、オレンジ丸のイベントを呼び出すキーのイベントの中身を実装していきます。


# 2. スクロールさせる複数のウィジェットを管理するウィジェットを作成する

スクロールさせる複数のウィジェットを管理するウィジェットを作成していくにあたって、最初に下図のようなウィジェット構成のWBPを作成します。（今回の記事では、作成するウィジェットのWBPの名前を「WBP_ScrollHUD」にします。）

![scrollhud_widgets.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/5668ae0c-74b0-fb93-4130-b9e4636ef213.jpeg)

|ウィジェット名|ウィジェットの種類|備考|
|:-:|:-:|:--|
| Scale Box | Scale Box | このウィジェットを一番上の親にします。<br>[こちらの記事](https://qiita.com/tuduru/items/1745f5f5df782164e6f7)に書いたように、このウィジェットのアスペクト比が変えられても、アスペクト比が保たれるようにするために使用します。 |
| Size Box | Size Box | 「Scale Box」ウィジェットと同じ理由で使用します。<br>[こちらの記事](https://qiita.com/tuduru/items/1745f5f5df782164e6f7)に書いたように、詳細パネルの「チャイルドレイアウト」＞「WidthOverride」「HeightOverride」にチェックを入れ、「Scale Box」ウィジェットのサイズを入力します。 |
| ScrollWidgetsPanel | Canvas Panel | スクロールさせるウィジェットを管理するために使用します。 |
| ScrollWidget_1~6| WBP_ScrollWidget | 上で作成したウィジェットです。今回の記事では、6つのウィジェットを下からスクロールさせていくので、1~6まで作成しています。 |

上のウィジェット構成のWBPを作成したら、「ScrollWidget_1~6」ウィジェットがウィジェット一覧で下図のように表示されているか、確認します。

![scrollpanel_before.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/7c008a01-3401-dbe5-0d8e-28ee20f3d46f.jpeg)

Canvas Panel ウィジェットを新しく作成し、上図の赤枠の「ScrollPanel」ウィジェットにドラッグアンドドロップすると、下図の赤枠のようになります。下図の赤枠に新しく追加された Canvas Panelウィジェットの中身が、スクロールされていく画面となります。なので、下図の赤枠に新しく追加された Canvas Panelウィジェットの下に、表示したい画面を作成するようにします。
（今回の記事では、簡単に Image ウィジェットと、Text ウィジェットを追加した画面を作成しました。）

![scrollpanel_after.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/cc3429d3-bda2-9c71-b5a3-be9be2ff18dc.jpeg)

「ScrollWidget_1~6」ウィジェットは、**ウィジェット一覧の上から順番に表示されていく**ため、ウィジェット一覧上における「ScrollWidget_1~6」ウィジェットの順番には注意するようにします。

また、「ScrollWidget_1~6」ウィジェットの詳細パネルの「スロット」＞「サイズX」「サイズY」は、一番上の親の「Scale Box」のサイズを設定するようにします。<br><br>


これで、スクロールさせる複数のウィジェットを管理するウィジェットの作成は終わったので、次は、管理している複数のウィジェットを、順番にスクロールさせていく処理を実装していきます。


# 3. 管理している複数のウィジェットを順番にスクロールさせていく

最初に、上で作成したスクロールさせるウィジェットの元とするウィジェット「WBP_ScrollWidget」で、先に作成しておくべき変数と関数を作成します。

まずは、下図の変数を作成します。ウィジェットをスクロールさせているアニメーションの途中で、次のウィジェットを下からスクロールさせる関数を呼び出すことに使用します。変数の型は「WBP_ScrollHUD」にします。（今回の記事では、変数名を「ScrollHUD」にします。）

![scrollhud.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/bb5765b2-5ace-fa95-6709-36345828a3e8.jpeg)<br><br>

次に、下図の関数を作成します。下図の関数では、次のウィジェットを下からスクロールさせる関数を呼び出すための「WBP_ScrollHUD」の参照を、変数「ScrollHUD」に格納します。（今回の記事では、関数名を「SetUp」にします。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/bc53ac91-0c29-552f-5fbb-0f7fcaf14132.png)

![setup_input.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/a3927731-54ae-462d-6233-51ca17056171.jpeg)<br><br>


最後に、下図の関数を作成します。「WBP_ScrollHUD」の方から、スクロールのアニメーションを再生できるようにするために作成します。（今回の記事では、関数名を「PlayScrollAnim」にします。）

![playscrollanim.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/c6d467d9-abee-2601-fef4-6895fd24cff4.jpeg)

これで、「WBP_ScrollWidget」で、先に作成しておくべき変数と関数の作成は完了です。<br><br>



次に、スクロールさせる複数のウィジェットを管理するウィジェット「WBP_ScrollHUD」のイベントグラフを開き、処理の実装に必要な変数を作成していきます。

まずは、スクロールさせるウィジェットを管理するための変数を作成します。変数の型は、上で作成した「WBP_ScrollWidget」にし、配列にします。（今回の記事では、変数名を「ScrollWidgetArray」にします。）

![scrollwidgetarray.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/0b5a97ec-b8ec-dad6-90a8-984f5483a927.jpeg)<br><br>


次に、次に画面下からスクロールしたいウィジェットの、「ScrollWidgetArray」における番号を保持しておくための変数を作成します。変数の型は「Integer」にします。（今回の記事では、変数名を「NextWidgetIndex」にします。）

![nextwidgetindex.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/b8aab031-b490-cbb1-c3c7-7c54d377d852.jpeg)<br><br>


最後に、下図の2つの変数を作成します。

![topscrollwidget.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/9411cd45-8b20-8ec0-1f43-adebf33a2d94.jpeg)

![bottomscrollwidget.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/2cad0b75-ecef-ef1f-5a9f-ba1f44916247.jpeg)

上図の「TopScrollWidget」変数は、下図における「ウィジェット1」を管理するための変数です。また、「BottomScrollWidget」変数は、下図における「ウィジェット2」を管理するための変数です。2つの変数の型は、「WBP_ScrollWidget」にします。

![scroll_exp3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/4745290b-9755-717f-9a55-c0c355eb15cc.jpeg)

これで「WBP_ScrollHUD」における、管理している複数のウィジェットをスクロールさせる処理に必要な変数の作成は完了です。<br><br>


変数の作成が終わったら、管理している複数のウィジェットをスクロールさせる処理で使用する関数を作成します。

まずは、下図の関数を作成します。下図の関数では、スクロールさせるウィジェットを管理する配列「ScrollWidgetArray」の初期化を行います。

![InitScrollWidgetArray.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/d9a7697b-9ccd-fff3-c0ab-50db9838183a.jpeg)<br><br>


次に、下図の関数を作成します。下図の関数では、インプットで受け取った番号に対応した、配列「ScrollWidgetArray」のウィジェットを取得します。（今回の記事では、関数の名前を「GetScrollWidget」にします。）

![getscrollwidget.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/06b2c723-6ef2-e88f-07aa-ced4a345b98e.jpeg)

「ScrollWidgetArray」関数のインプットとアウトプットは、下図のようにします。アウトプットの型は「WBP_ScrollWidget」にします。

![getscrollwidget_inputoutput.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/20cb3d28-b8d5-e429-92b6-15c1dc239f93.jpeg)<br><br>



最後に、下図の関数を作成します。関数の図は、ノードの横幅が長かったので、2枚に分けて表示しています。下図の関数では、次にスクロールしたいウィジェットを表示して下からスクロールし始めるとともに、不要になったウィジェットを非表示にします。（今回の記事では、関数の名前を「BeginScrollNextWidget」にします。）

![beginscrollnextwidget_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/c6de07f6-d69c-4c44-366c-f280c0ce2a1a.jpeg)

![beginscrollnextwidget_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/f7503209-ba82-7b65-bf0a-7ba465188a42.jpeg)

これで、管理している複数のウィジェットをスクロールさせる処理で使用する関数の作成は完了です。<br><br>


次に「WBP_ScrollHUD」のイベントグラフで、「WBP_ScrollHUD」の初期化処理と、管理している複数のウィジェットをスクロールさせる処理の前の呼び出し処理の実装を行います。

「WBP_ScrollHUD」の初期化処理は、下図のようにノードを組みます。スクロールしていくウィジェットの初期化処理と、スクロールしていくウィジェットを管理するための変数の初期化処理を行います。

![construct2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/9d0eee0e-6792-f89f-4b5a-802c860ff6e2.jpeg)<br><br>

管理している複数のウィジェットをスクロールさせる処理の前の呼び出し処理は、下図のようにノードを組みます。特定のボタンを押したら、ウィジェットのスクロールを開始し始めるようにします。（今回の記事では、「M」キーを押したらスクロールが始まるようにします。）

![startbutton.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/3e733691-4003-32c9-612c-17a48f227067.jpeg)

これで「WBP_ScrollHUD」で実装すべき処理の実装は完了です。<br><br>


最後に、再度「WBP_ScrollWidget」を開き、スクロールのアニメーション中に呼び出す処理の実装を行っていきます。

![scrollanimation.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/28096492-ed51-0861-a9f4-6efa780da00d.jpeg)

上図のオレンジ丸のキーをダブルクリックすると、イベントノードを開くことができます。（イベントノードの名前を変更することができるので、今回の記事では、開いたイベントノードの名前を「BeginScrollNextWidget」とします。「WBP_ScrollHUD」の関数名と名前を同じにして、ややこしくしてしまい、申し訳ございません。）

開いたイベントノードを利用して、下図のノードを組みます。

![beginscrollnextwidget_scrollwidget.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/3f236994-3107-79c7-903c-ab8c8996dd00.jpeg)

これで、スクロールのアニメーション中に呼び出す処理の実装は完了です。<br><br>


作成した「WBP_ScrollHUD」をビューポートに追加する処理を書き、実際にゲームをプレイして、スクロールアニメーションを再生するボタンを押してみます。

下の動画のように、「WBP_ScrollHUD」で作成した「ScrollWidget1~6」ウィジェットがつながって、順番にスクロールされてくるようになっているか確認します。

<iframe width="640" height="360" src="https://www.youtube.com/embed/6D-0u3ihDZQ" title="scroll widgets 1" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
<br><br>

これで、スクロールするウィジェットの作成は完了ですが、スクロールの速度を変えたいという方もいらっしゃると思うので、スクロールの速度の変更も行っていきます。


# 4. スクロールの速度を変更する

スクロールの速度を変更するために「WBP_ScrollWidget」の関数「PlayScrollAnim」を開きます。

「PlayScrollAnim」関数の「Play Animation」ノードの、下図の赤枠の「Playback Speed」を変更することによって、スクロールの速度を変更できます。「Playback Speed」に「2.0」と設定すると、スクロールの速度が2倍になります。

![playscrollanim2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/6053f18f-8078-a0ce-d394-f65f19ef0764.jpeg)<br><br>

下の動画は、「Playback Speed」に「2.0」を設定し、スクロールの速度を2倍にしたものです。

<iframe width="640" height="360" src="https://www.youtube.com/embed/kALpD8wjIxE" title="scroll widgets 2" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
<br><br><br>



以上で今回の記事の内容は終了です。
最後まで読んでいただき、ありがとうございました。