みつまめ杏仁

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

チャットUIを作る

6

 ListViewはまた今度時間作っていじってみようと心に決め、VerticalBoxでスクロールアウトした部分の処理について考えることにする。できれば削除せずににひたすらスクロールさせれることができればいいのだけど。短いとはいえ2分程度の観戦時間でもかなりの量のフキダシを抱えることになるだろうから、適度に軽くしてやらないといけない。プログラマにお願いしたいところだけど、見た目の調整も含め設計をやっている以上こちらである程度カタチにしてからの方が、問題点を見つけやすいし改善点についても相談しやすくなる。デザイナーが何をしようとしているのか、どういう部分の見た目にこだわっているのか、といったようなことが口頭だと伝わりにくいので、それなりに動くプロトタイプは結果的に無駄な連携コストを下げることができると思う。実をいうと単に作ってみたいだけだったりする。

 

 まずは確実に画面外に出たかどうかが分かれば、その要素を削除して、間が詰まったことを悟らせないようにする。まず思いつくのは移動した分を戻す方法。

 

f:id:hiyokosabrey:20190615214502p:plain

 

 要素が削除されると当然次の子要素が上がってくる。上に詰められた高さぶんを瞬間的に移動させて、何事もなかったかのようにしないといけない。 

 

f:id:hiyokosabrey:20190616201829p:plain

 

 配列の削除と位置移動を瞬間的に行うことになるので処理落ちした時に大丈夫か心配にはなるけど、その辺の危険性はこのプロトタイプができてからプログラマに訊いてみよう。もっと素敵な方法があればあとから構造を変えればいい。あらかじめ一番上にスペーサーを入れておいて、フキダシを消してからサイズを変更するとか、Paddingの設定でスキマを調整するのもありかもしれない。それはそれで、投稿数が多くなれば危険か。VerticalBoxを使わないというのもありかもしれない。おっといけない。プロトタイプは作ってから検証しないとな。どんどん作ろう。

 

 画面から出たかどうかの判定はどうするか。フキダシ毎に高さが変わるので、フキダシの高さを保存しておく変数が必要だ。画面にいくつも並ぶからそのぶんの変数が要るとなると配列だな。

f:id:hiyokosabrey:20190615212243p:plain

  これは、イベントディスパッチャーから返ってきた値を受け取るイベントがあったから、そこで積もう。

f:id:hiyokosabrey:20190615220503p:plain

  保存した高さは、画面外に出た量と比較するときに使って、また位置を戻すときの量にもなる。設定したMarginの分も入れとかないと。

 

 次は削除イベント作ろうかな。まずはカスタムイベントを置いて、と。

f:id:hiyokosabrey:20190615224133p:plain

 VerticalBoxから一番上に積んであるフキダシ、つまり子要素の削除だから、child で検索すると・・・あった。Remove Child Atノード。

f:id:hiyokosabrey:20190615224555p:plain

 Index番号は常に先頭を削除するから 0のままでOKだ。

 削除したぶんの高さを移動するから、Set Render Translation ノードをつないで。

f:id:hiyokosabrey:20190615225327p:plain

 VerticalBoxの座標は、positionCurrent 変数が持ってるから、そこから差し引けばいいかな。VerticalBoxの子要素削除と移動は処理に間を空けたくないから、事前に計算しておこう。

f:id:hiyokosabrey:20190615230138p:plain

 

 あとは、高さの配列も先頭のやつを削除しておかないとズレてしまう。

f:id:hiyokosabrey:20190616003817p:plain

 

 現在地の座標を下げたら、目的地の座標も下げないと。

f:id:hiyokosabrey:20190616004123p:plain

 よし、ひとまずこれで必要そうな処理はできたはず。このイベントを呼ぶためにチェックするのは座標を更新してるTickで。

f:id:hiyokosabrey:20190616005631p:plain

 

 さてどう比較するかだけど、VerticalBox は画面の下から上に向かって伸びていく。Translation の値は0から増えていくから、はみ出すころには画面の高さを越えてるはず。今回解像度は1080p想定だから、これをスクロール量から引けばいいのか。

f:id:hiyokosabrey:20190616012144p:plain

  こうかな。

f:id:hiyokosabrey:20190616014648p:plain

 よし試してみよう。

f:id:hiyokosabrey:20190616111906g:plain

 ってあれ?

f:id:hiyokosabrey:20190616193504g:plain

 なぜ戻る?目的地と現在地を一緒に戻してるからズレないはずだけど・・・

 

 あ、ここか!

f:id:hiyokosabrey:20190616195708p:plain

 高さをキャッシュしている配列の先頭がいなくなってから目的地を戻してる。それはズレるな。悔しい。順番を逆にしないと。

f:id:hiyokosabrey:20190616195924p:plain

 ふう、これで大丈夫。再生してみても問題なし。

 今は処理に余裕があるから問題ないように見えているだけかもしれないけど。

 

 そうだ、フキダシの追加と削除は随時いろんなタイミングで行われるから、 Tick処理の停止を入れておこう。

 Booleanでフラグを作って。

f:id:hiyokosabrey:20190616112749p:plain

 まずはここで止めねば。

f:id:hiyokosabrey:20190616114019p:plain

 そして初期値が false だからこのWidgetがViewortに置かれた時点ではTickの処理はここで止まり、先へは走らないようになった。となると、このTickを動くようにする蛇口に相当するトリガーのようなものが必要になる。それは、フキダシを追加した後だな。

 バインドしたイベントディスパッチャーの受け取りイベントの最後で、フラグを true にする。ただしここはフキダシが追加される度に来るから、DoOnce ノード入れておこう。

f:id:hiyokosabrey:20190616181131p:plain

 これで、初めてフキダシが追加されて、高さの値が返ってきたらTick開始となる。

 あとは、フラグを false にする部分だけど、フキダシの削除が決定したBrachのところが最適だろう。Tickは常時ものすごく短い間隔で処理されるから少しでもタイムラグをなくしたい。

f:id:hiyokosabrey:20190616181847p:plain

 

 この辺で一旦流れを確認してみよう。

 

1.このWidgetが Viewportに 追加されるとき isAnimEnable は false だからTickは動かない

2.フキダシ「追加」のイベントが呼ばれる まだ isAnimEnable は false

3.バインドしたフキダシWidgetから値が返ってきた ここで isAnimEnable を true

  ※初回の1回だけ

4.Tick が動きだして、VerticalBox が移動を始め、はみだしチェック常時行う

5.はみだし量が先頭のフキダシの高さを超えたので isAnimEnable を false にして Tick止める

6.フキダシ「削除」のイベントしてVerticalBoxの位置を戻す

7.フキダシは随時追加されるたびにスクロールの目的地は増え続けている

8.Tick再開・・・

 

 おっと、 isAnimEnable を 再び true にするの忘れてた。

 フキダシ削除イベントの最後でいいかな。

f:id:hiyokosabrey:20190616200127p:plain

 よし、これで動かしてみて問題なさそうだったら次に進める。

 

f:id:hiyokosabrey:20190616200502g:plain

 大丈夫そう。ちょっとグラフを眺めてみるか。基本の処理はスクロール担当の EventTick と、フキダシの追加と削除の 3つだ。

 

・EventTick

f:id:hiyokosabrey:20190616223018p:plain

・addFukidashi

f:id:hiyokosabrey:20190616223234p:plain

・removeFukidashi

f:id:hiyokosabrey:20190616223531p:plain


あとは、ダミーテキスト用の関数。

f:id:hiyokosabrey:20190616223913p:plain

 

 フキダシの表示は大体できたも同然だな。左右のレイアウト切り替えと顔アイコン、フキダシのしっぽは、パーツを追加すればいい程度だしそんなに心配するような難しさじゃないと思いたい。やっぱりいよいよ入力フォームかな。なんだか緊張する。

 硬くなった筋をほぐすように首と肩を動かす。プログラマたちの談笑が聞こえる。そういえばずっと聞こえていたような気がするが、それだけ集中できていたということだろう。

 さた、フォームはやったことないから、調べないとな。

 

 

つづく