みつまめ杏仁

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

セリフの表示の速さを調節するあれのあれ《後編》

秋草の花粉かホコリかわかりませんが鼻水とくしゃみが止まりません。せっせとティッシュの山を築き上げつつ、とりあえず座っている頭の高さを越えるまでに書き上げようと思います。

前回の続きです

 

limesode.hatenablog.com

 テキストをタイプライターのように一文字ずつ表示するとこまで作りました。

セッティング用のUIを作っていきます。

 

調整に必要なパーツはなんでしょうか?

タイピング速度が設定できればいいのですがここで、どういった方法で調整したいのか考えます。

  • 数値入力は面倒
  • 直感的にやりたい
  • 細かすぎるのはやだけど、微調整したいかも

とかなんとか検討の結果、スライダーが適任かと思われます。

ただしマウスの移動量は物理的なものなので、スライダーの変化の幅を大きくすると、微調整しにくくなります。下図はちょっと極端な例ですが同じ距離を移動したときの変化量を電卓で調べてフレームアニメーションにしたものです。

f:id:hiyokosabrey:20200921223245g:plain

 

ちょっと極端な値も見てみたいかもしれない。

そこで補助機能としてスライダーの最大値を変更できるようにします。

ここは微調整しなくてもよさそうなのでスピンボックスで。

気になったらスライダーに替えればいい。

あとはテスト用に仕込んでおいた 待機時間を調整するやつ。

これもスピンボックスで。

 

 

というわけで、

さっそく新しくWidgetを作成。

f:id:hiyokosabrey:20200921220622p:plain

このWidgetはあくまでも検証用です。好みの値を試しながら、議論して最終的な値を確定させるための役割なので、確定したら不要になります。

ですので肩の力を抜いて適当に置きたいものを置いてちゃちゃっと作ります。

 

キャンバスにパーツを並べていきます。

下のようなレイアウトにしてみました。

f:id:hiyokosabrey:20200921220715p:plain

ヒエラルキーはこのようになりました。CanvasPanel以下の階層は平たんです。

f:id:hiyokosabrey:20200922000230p:plain

左側の3つのTextBlockはラベルです。右側の4つはブループリントと連動します。

まず、一番右上の TextBlock は スライダーの値を流し込むので、Is Variable を有効にします。

f:id:hiyokosabrey:20200922000418p:plain

適当に初期値を決めておきます。

f:id:hiyokosabrey:20200922000704p:plain

なんとなく 0.1 くらいでいいかと。

 

次に スライダーの設定を確認。

Appearanceの項目を編集します。

f:id:hiyokosabrey:20200922001432p:plain

Value は 初期状態の値としてなんとなく決めた 0.1  にしておきます。

Min Value(最小値)と Max Value(最大値)もなんとなく入れておきます。

最小値の 0.0167 は 60fps想定で、 1/60=0.01666666... から。

0 にすると停止します。

 

次に最大値のスピンボックス

こちらは Content の項目

f:id:hiyokosabrey:20200922003035p:plain

これもなんとなくな値を入れておきます。

ただし Value(初期値) は スライダーの Max Value と同じにしておきます。

 

次は 待機時間のスピンボックス

f:id:hiyokosabrey:20200922003403p:plain

これもなんとなくな値を入れておきます。

Value(初期値)は、テキスト表示用Widgetで変数の初期値として設定した値です。

 

UIパーツの設定ができたので、イベントを用意します。

On Value Change (*) という便利なイベントがあらかじめ用意されています。

まず スピンボックスを選択した状態で

f:id:hiyokosabrey:20200922010045p:plain

Detailタブを下の方までスクロールさせます。

f:id:hiyokosabrey:20200922010301p:plain

Events の項目にある On Value Changed の右の+ボタンをクリック。

すると 自動でグラフに切り替わります。

f:id:hiyokosabrey:20200922010538p:plain

 

このイベントにつないでいく前に必要な変数を2つ用意します。

f:id:hiyokosabrey:20200922004218p:plain

プロジェクト内に作ったWidgetは、変数の型として扱うことができます。

WB_TextType は前回の記事で作ったWidgetです。

この変数の Expose on Spawn を有効にします。

f:id:hiyokosabrey:20200922004736p:plain

 

変数が揃ったので、イベントにつないでいきます。

f:id:hiyokosabrey:20200922011231p:plain

右端は、WB_TextType型の変数を通して中に用意したカスタムイベントを呼び出して値を渡しています。

 

Float型の値をText型のピンにつなげようとすると、自動でキャスト(型変換)ノードを挟み込んでくれます。

このキャストノード、初期設定だと小数第3位で四捨五入するので、少し設定を変えます。▼をクリックしてたたまれたノードを展開します。

f:id:hiyokosabrey:20200922011850p:plain

一番下の Maximum Fractional Digits を 4 に変更。

これで、0.0167 が 0.017 にならなくなります。

 

スピンボックスも キャンバス の方 でパーツを選択しておいてから、On Value Changed の横にある 緑色の+ボタンをクリックします。

グラフはこんな感じです。

f:id:hiyokosabrey:20200922013657p:plain

最大値のスピンボックスは、値が変更されると即座にこのイベントが呼ばれ、その瞬間の値がピンから出てきます。それをすかさずスライダーの最大値にセットしています。

 

一方の待機時間のスピンボックスは、テキスト表示用Widgetに値を渡しています。

 

ちなみに緑の+ボタンは、イベントノードが作られると、View ボタンに変わります。

f:id:hiyokosabrey:20200922014052p:plain

クリックするとそのノードの場所へジャンプします。

こういった細かい気遣いがUE4の好き。

 

これでこのWidgetは完成です。

 

このセッティング用Widgetを前回表示テスト用に作ったレベルブループリントに追加します。

f:id:hiyokosabrey:20200922100620p:plain

 WB_TextType型の変数の Expose on Spawn を有効にしているので、初期値として直前のCreate Widget ノードからの ReturnValue(戻り値)を渡すことができます。

 

これで、セッティングWidgetから テキスト表示Widgetのイベントを呼び出せるようになるので、パーツは全てそろったことにはなります。

f:id:hiyokosabrey:20200922101747j:plain

 ただマウスカーソルが常時表示でないし、テキストは一つだけど永遠に次のテキストに切り替わらないので、とりあえず待機時間の仕組みを確認するための処理を追加します。

f:id:hiyokosabrey:20200922102757p:plain

テキスト表示が完了した際に通知を受け取る必要があります。そこで イベントディスパッチャー と バインド(紐づけ) しておきます。

 つながっていた GoTypingノードと入れ替えます。

f:id:hiyokosabrey:20200922103631p:plain

ここにカスタムイベントを追加

f:id:hiyokosabrey:20200922103942p:plain

白いラインが途切れて GoTypingが呼ばれなくなったので、バインドノードの後ろに追加します。

カスタムイベントを呼び出すには、My Blueprint > Graphs > EventGraph の中にあるのをドラッグ&ドロップします。

f:id:hiyokosabrey:20200922104503p:plain

f:id:hiyokosabrey:20200922104635p:plain

続けて、マウスカーソルの常時表示のために、PlayerController が持っているフラグを有効にします。

f:id:hiyokosabrey:20200922105000p:plain

GetPlayerController ノードを取り出してそこから、show で検索すると見つけやすいです。

f:id:hiyokosabrey:20200922105334p:plain

これでようやくすべてが機能するはずです。

 

 

確認してみます。

スピードの値を小さくすると残像が長く伸びるのがわかります。

f:id:hiyokosabrey:20200922110305j:plain

0.0167 の値で、 StandAloneで実行して動画キャプチャして数えてみると、おおむね 57文字表示されてました。小数点を扱うので丸め誤差もあるかもしれない。どちらにしろ速くしても目で追いかけるのは無理なので安定するほどほどのところで最小値を決めたい。この辺の値を探る目的で作ったので、作った意味はそれなりに得られたと思います。ちなみに 0.1 ではきっちり10文字表示されました。

また、テスト表示ということでほぼ負荷を気にしない作りなので、0.0167以下の値  0.001 (1ms?) だと更に高速に表示されます。

 

こんな感じのサンプルを作ることで、プロジェクトの偉い人と一緒に値を決めたり、感覚を共有できます。

 

今回のテキスト表示は、タイピング速度の検証を優先したので、テキスト表示自体はすごくシンプルで、任意改行や文字修飾に対応できていません。あとは欲しい機能に合わせてアレンジしたり工夫すると面白くなると思います。

 

おまけ

テキストをあと何種類か追加してローテーションさせてみます。

レベルブループリントにまず変数を3つ用意

f:id:hiyokosabrey:20200922144345p:plain

 

バインドノードと イベント呼び出しノードの間でマクロと変数の初期化を行います

f:id:hiyokosabrey:20200922144741p:plain

マクロの内容は以下

f:id:hiyokosabrey:20200922145017p:plain

MakeArrayノードを使って好きなだけつなぎます。

つなぐのはこのノード。

f:id:hiyokosabrey:20200922145200p:plain

順番入れ替えや差し替えがラクです。

ピンを増やすときは Add pin + をクリック。いらないピンは、そのピンの上で右クリックして Remove array element pin を選択すると削除できます。

 

お気に入りのキャラを表示して、いい感じのセリフをしゃべらせると楽しさがアップします!たぶん!

 

 

マクロができたら、仕上げにテキストの順番を進める部分を作ります。

f:id:hiyokosabrey:20200922145843p:plain

マクロ内で、テキストの最大数を調べてあるので、その数で剰余を計算すると最大数までの範囲でループするような結果になります。剰余はほんとに便利なので当ブログでもよく登場します。ブループリントだと 「%」 マテリアルだと 「fmod」 です。

テキストを表示するたびにカウンタである TextIndex 変数を1加算しているので、次回表示する際は新しいテキストになっていて、最大数までカウントするとまたゼロに戻って・・・というのを繰り返します。ブランチノードで判定するよりシンプルです。

 

動画を撮ろうかと思ったのですが、ものすごく地味な動画になりそうなので、保留にします。そんなにややこしい構成ではないと思うので、興味が沸いた方はぜひ試してみてください。リクエストがあれば・・・考えます。

 

今回は以上です。

メッセージ表示のUIって、いざ作ってみるといろいろ工夫できて面白いですね。いい感じにできると、あとはシナリオとキャラがあればゲームができそうな気さえします。

なんとかティッシュに埋もれる前に書ききることができました。

鼻がひりひりします。

分かりにくいとことか、あれれ~おっかしいぞー?みたいなとこあれば容赦なくツッコミお願いします。

最後にちょっと前にCEDECの講演で話題になったキーワードについて、自分の思っていることをしゃべらせてみたのを貼っておきます。

f:id:hiyokosabrey:20200922180325j:plain

f:id:hiyokosabrey:20200922180345j:plain

 

ではでは

ステキな テキスト表示ライフを!