みつまめ杏仁

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

チャットUIを作る

4

 ミーティング中に出た話はほとんど頭に入ってこなかった。珍しくいつもより短く20分ほどで解散となったが、早く続きを触ってみたくて落ち着かなかったのだ。何となくイメージはするものの、ブループリントは直接ノードを手で並べながら試行錯誤したい。どんな便利な道具や部品に出会えるか想像するだけでワクワクして気が逸る。終わるとすぐ席に戻ってきて再生。さっきまで触ってた感触を取り戻した感じがして落ち着いた。f:id:hiyokosabrey:20190519110126g:plain

 ふむ。下からせり上がるようにするためには、まずはVerticalBoxの位置を画面下に移動させる。そこからフキダシの高さ毎に、せり上げていく処理が必要だ。

 フキダシWidgetは、文字列を受け取って表示するだけだから、文字列をフキダシに流し込んだあと自身の高さを調べて返せばいい。それを返してもらったレイアウト用のWidgetがその高さを元に移動量を計算して動かしてやればいいだろう。

 

f:id:hiyokosabrey:20190526122640p:plain



 

 まずは、フキダシから高さを返してもらう部分を作るか。

 フキダシから返事をもらうにはイベントディスパッチャーを使えばいいだろう。フキダシWidgetを開いてイベントディスパッチャーを追加する。名前は ed_resultHeight でいいかな。Inputsのピンを一つ追加して、返す値は整数(Int)じゃないだろうから Float型で。名前はとりあえず Height としておこう。

f:id:hiyokosabrey:20190524235925p:plain

 これを、テキストをセットしているノードの続きに Call でつなぐ。

f:id:hiyokosabrey:20190525004801p:plain

 このままだと、0.0 しか返さないのでランダムな数字を出すようにしたい。

f:id:hiyokosabrey:20190525004621p:plain

 これで、60、120、180 の3種類を返すはずだ。いったんコンパイルして保存する。

 次は、レイアウトWidget側でイベントディスパッチャーの値を受け取る準備をしないとな。フキダシを追加するときに、CreateWidgetノードを使ってたからこのReturnValueピンからバインドしよう。

f:id:hiyokosabrey:20190525001535p:plain

 ReturnValueピンからドラッグして bind と入力して検索する。

f:id:hiyokosabrey:20190525002114p:plain

 あった。これをどこにつなごうか。この左右に振り分けてるのどうせいらないから、ここにしよう。

f:id:hiyokosabrey:20190525002946p:plain

 値をもらって処理するのはイベントだから、カスタムイベントをつないで、PrintStringで確認してみよう。

f:id:hiyokosabrey:20190525004935p:plain

 よし、これで再生だ。

f:id:hiyokosabrey:20190525005421g:plain

 あれ?PrintStringは?動いてない?おかしいな、とりあえずBreakPoint貼ってみるか。

f:id:hiyokosabrey:20190525005721p:plain

 

 ・・・

 

 さっきと同じで変化はない。うーんなぜか止まらない。コンソールにも Error や Warning の類は出ていない。イベントディスパッチャーをCallしてるとこにPrint Stringを置いてみよう。

f:id:hiyokosabrey:20190525010332p:plain

 どうかな?

f:id:hiyokosabrey:20190525010548g:plain

 ここはちゃんと動いてる?

 そうか、こんなに華麗にスルーされているということはフキダシ側のイベントディスパッチャーのノードが処理されるタイミングだと、まだレイアウトWidget側のバインド処理が走っていないという可能性が高そう。であればバインド処理を前に持ってきてみよう。

f:id:hiyokosabrey:20190525012148p:plain

 CreateWidgetの直後に置いたらどうなるか・・・

f:id:hiyokosabrey:20190525012451g:plain

 ばっちりだ。これは次から気をつけないとな。

 自分だけ待ち合わせ時間を間違って記憶してて、遅刻して置いてけぼりくらってるのに気づかず「みんな遅いな」というシチュエーションがふと頭に浮かんだ。

 よし、少し前進。教訓も得た。次は、値を返す仕組みはこのままでいけそうだ。フキダシのサイズ調整を作るか。たしかブログで見た気がする。これなんか使えそう?

 limesode.hatenablog.com

 ふむふむ、まずはフキダシのベースになるテクスチャを作ろう。

 Photoshopでフキダシっぽい感じのイメージを作ってみる。ここからテクスチャ用にRGBと透過部分のアルファチャンネルを用意してTarga形式で書き出す。

 

f:id:hiyokosabrey:20190525133453p:plain

 

 これをインポートしてUMGで使えるようにする。さっそくフキダシの下敷きにしていたImageにセットしよう。 Draw As を Box にしてMargin を 0.5 にすればOK。

 f:id:hiyokosabrey:20190525194814p:plain

 Imageは、サイズが可変だから、アンカーをタテヨコ両方向のストレッチにしておかないと。

f:id:hiyokosabrey:20190525195115p:plain

 ストレッチにするなら、ぴったりフィットさせないと意味がないから、Offsetは全て0にする。

f:id:hiyokosabrey:20190525201225p:plain

 Image は子供を持つことができないので、 Image と TextBlock 同士で直接干渉し合うこともできない。親である Canvas は子供の Size を反映することができる。したがって Image は親のキャンバスに合わせればよいということになる。Image は TextBlockのサイズなんかどうでもよくて、親のサイズにひたすら最大まで合わせればOKなのだ。

 TextBlock は TextBlock で流し込まれた自身の持つフォントの大きさとテキストの量で自動的にサイズが変わってほしいから、Size To Content にチェックを付けてやる。Canvas は、そんな TextBlock の可変を、さらに外側から暖かく寛容に包み込んでほしいので、Canvas の Size To Content も有効にしなければ・・・

 

f:id:hiyokosabrey:20190525195429p:plain

 そうだった、一番上の階層にあるCanvasって Slot の項目がないんだった。 これじゃSize To Contentが有効にできない。しかたがないもう一段Canvasパネルで括るか。ついでに名前も整えておこう。

f:id:hiyokosabrey:20190525200016p:plain

 UMGで配置したパーツは変数として扱うこともできる。グラフに置いた時に全部同じカラーで見た目に分かりにくくなるので、パーツの種別名を残して命名するようにしているが、我ながらナイスアイディアだと思う。

f:id:hiyokosabrey:20190525200429p:plain

 アンダーバーが消えるのは何故だろう。フォントのせい? これはこれで いいね してる人がいるからこの仕様なんだろうけども、誰か知っているなら明快な答えを教えてほしいものだ。

 で、Size To Content にチェックをつけると・・・

f:id:hiyokosabrey:20190525212731p:plain

 うーん、テキストの大きさには追随してる感じだけど余白が無いな。

 テキストを変えてみる。改行も入れてみよう。

f:id:hiyokosabrey:20190525212849p:plain

 ぴったりフィットしすぎだろう。余白付きでフキダシの真ん中に来てほしいからなぁ。ブログではブループリントで TextBlock のサイズを調べて調整してるけど、なんか他に方法ないかな。

 そうだ SizeBox を試してみよう。TextBlock を SizeBox の子供にして。SizeBox 自身にも Size To Content の設定をしておかないと。確か 子供の方に Padding の設定があったはず・・・よし、あったあった。

f:id:hiyokosabrey:20190525213308p:plain

 おお、これはいい感じ!SizeBox ステキすぎる。できれば Canvas にこの設定があればよかったんだけどな。

 

 ヒエラルキーはこうなった。

f:id:hiyokosabrey:20190525213835p:plain

  あとは、この Canvas のサイズを調べてイベントディスパッチャーに渡せばいい。サイズを調べるには、この Force Layout Prepass を間に入れて、Get Desired Sizeか。

f:id:hiyokosabrey:20190525222641p:plain

 さっそくテストしてみる。

f:id:hiyokosabrey:20190525223243g:plain

 これじゃ、分からないな。ダミーのテキストを用意してみるか。

 

 こういう場合は、まず関数を一つ新しく作る。カウントアップする変数があるので、それをもらって返すようにしよう。配列型のテキストは、もちろんローカル辺変数にする。関数の中だけで完結するようにしておけば、他からの参照もないので要らなくなったら簡単に捨てられる。

f:id:hiyokosabrey:20190525231725p:plain
  エラーが出ても面倒なので、配列が用意されていなければ固定のテキストを出すようにする。

 

 さらにこの変数を ピュア型にすると使い勝手もよくなるはず。

f:id:hiyokosabrey:20190525225214p:plain

 グラフに戻ってつないでみる。

f:id:hiyokosabrey:20190525224913p:plain

 ピュア型にすると白いラインとは別のところに置けてスッキリするので便利。

f:id:hiyokosabrey:20190525230009g:plain

 おお、なんかできてきた感ある。ログを見てみよう。

f:id:hiyokosabrey:20190525232255p:plain

 それなりに値を受け取って来られているようだ。

 

 いい手応えを感じる。このまま今日中に作り切れるといいな。そう思いながら体を伸ばして軽くストレッチをする。ふと時計を見ると間もなく12時だ。今日は紀伊國屋に行かないと。午後からは VerticalBox を動かすところに進もう。

 人がばらばらと席を立って動きだす。自分もサンダルから靴に履き替えてフロアを出る。エレベーターを待っていると、どこからか雨の匂いがした。

 

 

つづく