みつまめ杏仁

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

UMGのテキストブロックで遊ぶ

とあるRPGの曲を作業用に聞きながらYoutubeの動画をチラ見してたら、テキストの表現方法がたくさんあったことに感動したのを思い出しました。で、ふと試してみようと思たったのが今回のネタです。過去記事で似たようなことをやってるのでその応用ってことになるのかな。

 

limesode.hatenablog.com

基本的に同じような作りです。ちょっと味付けが違う程度なので、細かい解説は省きます。

今回やろうとしている機能は2つ。

  • 1文字ずつタイプライター風に表示
  • 文字を震わせる

 

1文字ずつ出すだけだったら、テキストブロックひとつあればいいのですが、バラバラにする必要があって、さらに改行もするのでちょっと面倒なプロセスが入ります。

 

大雑把ですが、

  1. 改行付きの文字列(String型)を受け取る。
  2. 改行文字(エンジン内ではShift+Enter)で区切って文字列の配列を生成。
  3. その配列を行毎のHorizontalBoxに格納。
  4. 文字をぶるぶるさせる
  5. 一文字ずつAlphaを1.0にする

というフローでやってみます。

 

まず吹き出しテクスチャ。前回の記事に倣ってグレースケールで作りました。

f:id:hiyokosabrey:20180418231516p:plain

インポート設定で、フィルターを ニアレストにしておきます。

f:id:hiyokosabrey:20180418231828p:plain

拡大縮小の際のフィルタリングでドットをそのままにする設定です。

 

UMGのキャンバスに表示のON/OFFをラクするためにキャンバスパネルを置いて、中に

フキダシ画像と、文字を流し込むためのHorizontalBoxを並べます。

f:id:hiyokosabrey:20180418232541p:plain

 4行分に対応。

一応 HorizontalBoxは Size to Content のチェックを入れてあります。

f:id:hiyokosabrey:20180418232834p:plain

このHorizontalBoxを4つに分けたことで、文字列を「行」ごとに分割することになった

 最大の理由です。ローカライズを考えるならもうちょっと対策した方がいい気もしますが、あとから改行位置を調整するのを前提とした作りにしています。

Hiearchyはこんな感じ。

f:id:hiyokosabrey:20180419223029p:plain

 

Widgetブループリントを編集していきます。

HorizontalBoxはすでにキャンバスに置いてあるので、扱いやすくするために、Event Pre Constrct で配列化しておきます。

f:id:hiyokosabrey:20180419223215p:plain

 ブーリアン型の変数は、いきなりブルブルしないようにするためのフラグです。今はまだ false 。

 

まず関数を3つ。

 

ひとつ目

文字列を分解して、新しく1文字づつのテキストブロックを生成する関数。

f:id:hiyokosabrey:20180419224615p:plain

 

2つ目

指定した文字列(Delimiter)が文中に見つかると、それを配列にバラして格納します。

f:id:hiyokosabrey:20180419231005p:plain

 Parse Into Array はとても便利なノードです。

f:id:hiyokosabrey:20180419230145p:plain

 デリミタで使用した文字は消滅します。何が便利かって個別の値(この場合は文字列)を1文で扱うことができるという点です。本当は改行文字のようなOSやプラットフォーム依存の文字は避けるのが基本ですが、今回はお遊びということで。

 

3つ目

外部から文字列を受け取って表示する関数。上の2つの関数を組み込みます。

f:id:hiyokosabrey:20180419231325p:plain

 For Each Loop の処理が終わったら、表示開始になりますが、ひとまずイベントグラフに戻ります。

 

Event Tick でぶるぶるする処理を用意します。

Event Tick は、この WidgetViewportにAddされた瞬間から動き出します。

f:id:hiyokosabrey:20180419231611p:plain

 ランダムに ポジションを動かしますが、今回は微妙な値が連続しないようにInt型の乱数にfloat型の値を掛けています。

 

ここでフラグを見ています。文字の数が確定してないうちから処理するのは無駄なので、フラグが True になるまで処理しないようにブロックしています。

 

タイプライター風の動きをするのが、このカスタムイベント。

f:id:hiyokosabrey:20180419232511p:plain

ポイントなのがこの部分↓

f:id:hiyokosabrey:20180419232958p:plain

過去記事 『キーリピート機能をつくってみる』でも書いています。

 

だいたい用意ができたので、仕上げに3つ目の関数を編集します。

For Each Loop ノードの、Complete ピンの続きです。

f:id:hiyokosabrey:20180419233347p:plain

まず表示を Visible にして、フラグを True にしたら、タイマーノードです。

フキダシが表示されたら、人は目で追います。そのタイミングで文字を表示するのは視線誘導の効果が台無しなので、少し待ってあげるためのものです。Function Name のところに、タイピング処理用のカスタムイベントの名前をセットします。

 

これで、できあがりです。

 

 

確認

あとは適当にレベルブループリントから呼び出して確認します。

f:id:hiyokosabrey:20180419234030p:plain

 

こうなります。

f:id:hiyokosabrey:20180419234615g:plain

そう、とあるRPGというのは、UNDERTALE です。

その登場キャラの一人、フラウィのセリフです。

もう一つキャプリました。

f:id:hiyokosabrey:20180419235219g:plain

多分、まったく効果はない気がしますが一応ネタバレ対策で英語版にしてみました。

アイツの笑い声がよみがえります。

 

だいぶ遅れて遊んだのですが、ほんといいゲームですね。

読み物としてテキスト表現にこれほど凝った見せ方をしたゲームいままであっただろうか、というところも感動しました。UI表示を考えるとき、システム的に汎用性を意識するものですが、そんなのお構いなし、って感じです。まだ遊んだことのない方、ぜひ一度ご賞味ください。クレジット画面も凄まじい作りこみです。

 

今回も目コピーネタでしたが、楽しいのでまたやろうと思います。

ではでは

ステキなテキストブロック ライフを!