みつまめ杏仁

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

テキストブロックのサイズを取得する2

前回、動的にテキストブロックに流し込んだ文字列の長さを取得してポジションを調整してみよう、という内容でしたが、

 

limesode.hatenablog.com

 Widgetコンポーネントにして表示すると Force Layout Prepass が効かなくなるということが判明しました。Widgetコンポーネント自体が、Experimental実装(実験的な実装)なので、今のところ諦めるしかないようですが、調べているとTickを進めると解決できそうな様子。さっそくいろいろ試してみていい感じになったのでメモ。

 

まずはテキストブロックのパーツを一つ仕込んだWidgetを用意。

f:id:hiyokosabrey:20160601225124p:plain

続けてテキストを受け取る関数を用意します。

f:id:hiyokosabrey:20160601230036p:plain

ゲームパッドのボタンアイコンを切り替えるしくみを入れているのでちょっとややこしい感じですが、右の方の SetText(Text) ノードで文字列を流し込んでいます。その次のノードで、Tickを1つ進めるためのカスタムイベント"ResetOnce"を呼び出しています。すでに用意しているのでつなぐことができています。

このSetTextノードの直後で、GetDesiredSizeできれば問題なかったのですが・・・

 

で、EventTickを進める部分は以下のようにつなぎます。

f:id:hiyokosabrey:20160601232033p:plain

DoOnceノードで Tickをせき止めています。このノードにある、Start Closed にチェックを付けることで好きなタイミングで一度だけTickを通すことが可能です。

 

この DoOnceを抜けた先で、テキストブロックのサイズを取得しています。

f:id:hiyokosabrey:20160601233916p:plain

"36"という値はテキストブロックの前にあるアイコンの分です。ようやく取得できたテキストブロックのサイズを、イベントディスパッチャーで返す仕組みです。

ここでパーツ用のWidgetは用意できました。

あとはこのWidgetを呼び出して並べるWidgetを作成すればほぼ完成です。

 

操作方法のガイドとして作ってみたサンプルを載せます。

f:id:hiyokosabrey:20160602002602p:plain

まず表示する内容を引数(配列)で受け取っています。

配列の数に合わせて作ったパーツWidgetを並べるので、数を確認するための変数 IndexCount を用意しています。この手の方法はいろいろあるのであくまでも参考程度で。

カスタムイベントがループ用につないであります。デリゲートで、イベントディスパッチャーで値が返ってこないと次のパーツが並べられないので、ForloopやForeachLoopは使っていません。

次に隣を見てみると、以下のようになっています。

f:id:hiyokosabrey:20160602003448p:plain

途中で、サイズを返してもらうためにイベントディスパッチャーにバインドしています。バインドを済ませてから、最後にテキストの内容をパーツWidgetの関数に渡しています。

表示位置のオフセットを保持しているのが、Vector2D型の変数 PartsPos です。

値が返ってきたらこの変数に加算して次に備えます。

f:id:hiyokosabrey:20160602003957p:plain

カウント用の変数に1を足して次のパーツ配置に向かうためにループ用のカスタムイベントを呼び出しています。

これで、必要な分のパーツを、文字列のサイズに合わせて並べることができます。

 

f:id:hiyokosabrey:20160602004706p:plain

これでドイツ語も怖くないです。

f:id:hiyokosabrey:20160602005037p:plain

いかがでしょうか。

この方法でいい感じなんですが、全部揃うまで数フレームかかってしまうところが懸念点です。でも画面が切り替わっていきなり操作ガイドが主張するのもUX的に考えると控えた方がいいので、あえて遅れてフレームインさせるくらいでちょうどいいと思います。

 

あくまでもWidgetコンポーネントで描画する際の方法なので、

普通にWidgetをViewportに描く分には、Tickを使わなくても大丈夫です。

 

ではでは

今回はこの辺で。