今回はコメントを頂いたのでその返答として書きます。コメントいただけると嬉しいですね。続けてきた甲斐があるってものです。
で、作ってみたのはこれ。
いくつかのアイテムを左右にスクロールさせて選択するメニューUIです。
今回アイテムの絵素材として FLAT ICON DESIGNさんとこのを使わせていただきました。
3つのWidgetアセットで構成します。
まず、選択用に並べるパーツとしての Widgetとフォーカス状態を表すWidget、
そして、これらをまとめるWidgetです。(※名前は適当です)
ではさっそく、並べる方から用意していきます。
WD_Item
UMGのキャンバスはシンプルです。
並べた時にくっつきすぎないようにCanvasPanel (Sizeは120x120)を置いて、中にImage を子供にして配置します。
つぎにGraphを編集します。
テクスチャを受け取る関数を用意します。
次にカスタムイベントを用意します。
これはフォーカスされているときと、されていない時で表示/非表示を切り替えるためのイベントです。カスタムイベント側の緑のピンは、右のSet Visibilityノードにある 緑のピンからドラッグ&ドロップすると、簡単に追加できて便利です。
以上で並べるためのパーツは完成。
次は、フォーカスされたアイテム用のWidgetを作ります。
WD_ItemFocus
これもキャンバスはシンプルな構成で十分です。
ただ大きいだけだと面白くないのでアニメーションを仕込んでみます。
キャンバスはこの辺で、次にGraphを編集します。
アイテムを切り替える際、見えない状態から始めないとタネがバレるので、カラーを透明にしておきます。
この Event Pre Construct につなぐと、エディット中から適用されるので、Add to Viewport したときのチラ見えを安全に防ぐことができます。
次はフォーカスされて表示を更新するカスタムイベントです。
フォーカスされるアイテムはプレイヤーの動作に応じて動的に変化するので、このイベントで、テクスチャを受け取ってアニメーションを再生しています。
以上でパーツのWidgetは用意できました。
次に、全体をまとめて管理するWidgetです。
WD_ItemList
まずUMGのキャンバスは以下の構成になります。
最初からあるCanvasPanelとは別に、新しく置いた CanvasPanel は、HorizontalBox をクリッピングする(CanvasPanel の外側は描画しない)ために用意しました。後述。
ヒエラルキーはこんな状態
HorizontalBox の大きさは、Size To Content にチェックをつけて有効にしておきます。
この時点で中身が空なので、左上に縮こまってます。
CanvasPanelの大きさは、実際に表示する大きさなので、アイテムWidgetのサイズと表示個数によって調整します。今回アイテムWidget1個のサイズが120x120で、7個が見えている状態にします。さらに両端に半分が見えるようにしたいので、合計8個分として 120 × 8 = 960 の幅で作成します。両端のチラ見せは、並んだアイテムの続きがあることを印象付けるためです。
今回アイテム120x120が 8個 並ぶ想定でサイズを決めました。
また、少し前のVerから、キャンバスの外側にも子供を表示する仕様がデフォルトになったので、キャンバスパネルの設定を変更する必要があります。
CanvasPanelを選んだ状態でのDetailsタブにClippingの項目があるので、これを探して変更しておきます。 Inherit → Clip to Bounds
最後に、フォーカス表示用のWidgetを、User Created の中から探してキャンバスに追加します。ZOrderの値を大きくして、手前に重なるようにします。
これは入れ子にはしません。
つぎに Graphの編集に移ります。
アイテムを半分チラ見せしたいがために、ちょっとだけ表示位置の調整が必要になります。
このために、Float型の変数を用意します。
CanvasPanel(CanvasPanelListと命名)のサイズを取得して計算し初期位置を求めます。
今回のスタイルのUIは、スクロール方向がキー操作と逆にしているので、アイテムWidgetの表示サイズをマイナスの値で扱うことにします。最初からマイナスにしておくことで計算が一つ減ります。
この辺の事前準備は、必要なパーツも最初からキャンバスに揃っているので、Event Pre Construct で行っています。
続いて Integer型の変数を2つ用意します。フォーカス中のIndex番号を保持するためのものと、アイテムを必要個数分生成して追加しつつスクロールの端をチェックするための2つです。
まん中の関数は、アイテムの中身をセッティングする関数です。内容は以下。
ここはプロジェクトのデータ管理方法によっては違うつくりになると思いますが、この関数で表示するためのアイテムを準備します。
後から追加しやすいことを考えて、テクスチャアトラスは作らず、バラバラで個数分用意しました。
200x200
それをTexture2D型の配列変数にあらかじめ登録しておきます。
大量のテクスチャアセットをインポートする場合に便利なのがこれ↓
コンテンツブラウザで、対象の画像アセットを複数選択しておいて右クリックすると選択できます。扱い方はこちらのブログに詳しく紹介されています。
【UE4】Sound Cueのパラメータを一覧して一括変更する方法 - SAT04 CREATIVE SPACE
サウンドアセット用の解説なのでパラメータは違いますが、基本的な操作は同じです。
次に、アイテムを並べていきます。 Forloop ノードを使って必要な個数分の処理を回します。
Create Widget したあとすぐに WD_Item型の配列変数に追加(Addノード)しています。これは、並べたアイテムを後からIndex番号で扱いたいからです。
HorizontalBoxに子供として追加すると自動的に水平方向(基本的に左から右)に並ぶことになります。
ひととおり並べ終わったら、フォーカス表示用のWdgetにテクスチャを渡すのと、アイテム名の表示を行う関数を用意して、Forloopノード Completeピンにつなぎます。
次はスクロールの動きを作る関数です。
慣れないとややこしそうに見えますが、このブログでもよく登場するやつです。
( 目的地 - 現在地 )× 減速率 を 現在地に足す ことで減速しながら目的地に向かいます。
減速率の 0.25 という値をいろいろいじって加減してみてください。
この関数を、Event Tick につなぎます。
次に、アイテムのフォーカス位置(FocusIndex)を増やしたり減らしたりするイベントを用意します。
左端のイベントノードは、一つはカスタムイベントですが、もう一つは、ボタンから生成したイベントノードです。作り方は簡単。編集モードをDesigner に切り替えます。
キャンバスのButtonパーツを選択した状態でDetailsタブの一番下にEvents という項目があります。この緑色の + ボタンをクリックすると、Graph に出現します。
このイベントで、FocusIndexの値が更新されたので、見た目に反映する必要があります。最後に関数をつないで完成です。
と言いたいところですが、あとひとつ関数を追加します。
これはフォーカスを切り替えた際に、非表示にしていたアイテムを戻す関数です。
このイベントの処理を簡単にまとめると、
という流れになります。
さっそくテストしてみましょう。
レベルブループリントから、ビューポートに追加します。
これで再生すると動きますが、キーボード操作用のイベントも追加しておきます。
再生してみます。
GIFなのでブラウザによっては速度がでないかもしれないですが、結構いい感じになったと思うのですがいかがでしょうか?左右の端に行くとループしているので反対側に一気に飛びます。
左右にある灰色の四角はUMGに用意されているもので、グラフィックを設定していないので、見た目はショボいですがちゃんと反応します。
今回決定処理はないですが、ひとまずそれっぽい挙動は作れたかと思います。
説明が分かりにくいところとかあればツッコミコメントをお願いします。
ではでは
ステキなアイテム選択UIライフを!