みつまめ杏仁

アンリアルエンジン(UE4)でGUIを作るためにゴニョゴニョしてます。UIデザイナーの皆様の助けになれば幸いです。

ポップするリスト表示を試してみたのでメモ

3人称視点のアクションRPGとかで、フィールドに落ちている何かを拾うと、ログ表示のように画面端に表示されるあれです。

原神をプレイしてて作ってみようと思い立ったUI表示ですが目コピーではないです。

f:id:hiyokosabrey:20210106233401j:plain

試そうと思ったきっかけは、

  • VerticalBoxに追加した UserWidgetが、自身を Remove from Parent したらどうなるのか?
  • ガシガシ追加しまくっても、一定時間経過で勝手に消えてくれるのであれば、追加する側が管理しなくてもいいのでは?

 

という安易な推測によるものでした。

 

で実際にやってみた作り方をメモメモ。

 

Widgetを2つ使います。

まず最初に作るのは、表示する子要素であるWidgetから。

f:id:hiyokosabrey:20210104214201p:plain

 

UMGのキャンバスには、まとめてアニメーションさせるための CanvasPanel を追加して、あとはその子供として Image(下敷き用)、Image(アイコン用)、TextBlock(アイテム名など)を配置。

f:id:hiyokosabrey:20210104214320p:plain

f:id:hiyokosabrey:20210104214643p:plain

↑ Image_Cover は登場時に白くフラッシュさせるエフェクト用です。

 

最初から配置されている CanvasPanel は、Canvas Panel Slot を持っていなくてサイズを使ったアニメーションができないので放置。

 

ここでポイントが2つ。

1つは、余白を作っておくことです。
f:id:hiyokosabrey:20210104215511p:plain

画面に見せたいパーツ(中身)の大きさより、CanvasPanelを少しだけ大きくします。

これが並んだ時のスキマになります。

VerticalBox に追加する際に Padding で調整すると、Paddingの余白はサイズのアニメーションに含まれないため、タイミングによってはかカクっとなるのが見えてしまいます。

f:id:hiyokosabrey:20210104224334g:plain ← CanvasPanelに余白

f:id:hiyokosabrey:20210104224408g:plain ← Paddingで余白



アニメーションは、 Open(出現用) と Close(退出用) の2つ。

 

Open

f:id:hiyokosabrey:20210104232906g:plain


Close

f:id:hiyokosabrey:20210104233140g:plain

もうひとつのポイントはここ。

なるべくSizeのアニメーションは最後までとっておきます。

f:id:hiyokosabrey:20210104234459p:plain

先に Scale と Opacity で見えなくしてから、Sizeのアニメーションをさせるようにすると、リストに追加があったときに見やすくできます。

アニメーションで動きをつけるのは、気づきやすさ(視認性)を上げるうえで有利ですが、静止しないと読みにくい(可読性が下がる)ので、調整は大事です。

 

UIを試行錯誤しながら作っているこの状況で、気を付けたいのがこの視認性と可読性のバランスです。

テスト用の文字列やアイコン情報を表示しても、内容については仮のものなので、無意識に表示内容をスルーしています。動きや雰囲気に注意が向いている分、そこさえ良ければ、もう出来た感じがしてしまうという罠です。実装後の確認とチューニングはしっかり行いたいものです。

 

あと、細かいことですが、出現と退出のアニメーションを別々で作っているのは理由があります。

適切な表示時間を、ブループリントでDelay ノードで調整したいからです。

いい感じの表示時間が確定さえすれば、後でタイムラインを一つにできます。

また、表示時間の調整を行う際に、自分以外の方に説明するのが簡単です。

「なんか短くない? 何秒?」

「(Delayの値)1.25秒です」

「2秒にしてみたらどんな感じ?」

「ちょっと待ってくださいね」

てな具合にやり取りができます。

 

というわけでキャンバスはこのくらいにして、続いてWidgetブループリントを編集。

Event Construct

f:id:hiyokosabrey:20210104233602p:plain

右下のノード Remove from ParentSelf を指定しているので、自分自身が消滅します。

 

再生するアニメーションが 2つあるので

上の例では、アニメーション終了検知のイベント は使用しないケース、

下の例は使用するケース。

f:id:hiyokosabrey:20210105235540p:plain

 

いくつかの変数をパラメータとして受け取るようにしています。

f:id:hiyokosabrey:20210105003141p:plain

Expose on Spawn を有効にしているので、この Event Construct が実行される時にはすでにパラメータを受け取っているという段取りです。

f:id:hiyokosabrey:20210105005147p:plain

最終的に Structure にしたほうがよさそうな気はします。

 

表示のためのセットアップは、ブループリントのスクショがコンパクトになるようにマクロにしています。

マクロの外に接続するようにしているのは、自分以外の方、もしくは未来の自分がブループリントを見た時に、少しでも何をしているか、何をしようとしているかを解りやすくするための気配りみたいなものです。

で、マクロの中身はこんな感じです。

f:id:hiyokosabrey:20210105004145p:plain

FormatTextノード便利ですよね。

 

これで表示する子のWidgetは完成です。

 

 ここからは、リストを並べるためのWidgetを作っていきます。

f:id:hiyokosabrey:20210104214209p:plain

 

UMGのキャンバスには、VerticalBox が一つ。

f:id:hiyokosabrey:20210106000647p:plain

 

次にWidgetブループリント

f:id:hiyokosabrey:20210106001444p:plain

簡単なテストということで、変化を楽しむためのカラーを配列に仕込んでいます。

セットしている配列変数は、LinearColor型です。

 

カスタムイベントを用意します。

f:id:hiyokosabrey:20210106002142p:plain

CreateWidgetノードに、先に作ったリスト用のWidgetを Class としてセット。

f:id:hiyokosabrey:20210106003214p:plain

変数の Expose on Spawn を有効にすると、この CreateWidgetノード経由で初期値を渡すことができます。

 

これで出来上がりです。

 

 

あとは適当なレベルを作って表示テスト。

f:id:hiyokosabrey:20210106003758p:plain

Inputノードで、スペースキーを押すと、カスタムイベントを呼び出す。

 

f:id:hiyokosabrey:20210106011549j:plain

Twitterに動画を上げてるので、動きのイメージはこちらから ↓

テキストの表示が TextBlock のままですが、動きは同じになります。

 

一応検証用に、VerticalBoxの子要素をカウントしてみました。

キャンバスに TextBlock を一つ追加して、EventTickで監視した数を常時表示します。

Get Children Countノードを使って調べます。

f:id:hiyokosabrey:20210106011833p:plain

Remove from Parent で消滅するタイミングでカウントが減ります。

f:id:hiyokosabrey:20210106012210g:plain

いい感じに動作しているようです。

 

ガシガシ呼び出しても、勝手に消えていくんで管理する手間が省けていいなぁ、と思いたいけど、実際には表示数に制限が必要だし、制限を越えた分はプールしておいて、空きができたら、プールが空になるまで逐次追加し続けたりしないといけない。

とはいえ、最初の推測通りの結果になったので、よかったよかった。

 

というわけで

今回はこの辺で

 

皆様、健康でよい一年になりますように

 

今年もよろしくお願いいたします