みつまめ杏仁

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

雑記::20210130

最近Twitterにあげたやつ

f:id:hiyokosabrey:20210130110333j:plain

動きは上のツイートから確認できます。

 

UE4がゲーム画面を描画するとき、いろんな計算用のバッファを使っています。その一つが SceneDepth です。

f:id:hiyokosabrey:20210130110649p:plain

ワールドに置かれたオブジェクトのカメラからの距離を保持しているバッファです。

それに対して、step ノードを使って遊んでみました。

 

ポストプロセスマテリアルを用意。

まず普通にマテリアルを作って、ドメインを変更する。

f:id:hiyokosabrey:20210130112539p:plain

あとはノードをつなぎます。

f:id:hiyokosabrey:20210130112310p:plain

↑左下のノードは、別途用意しておいたマテリアルパラメータコレクションからScalarParameterを一つ。

f:id:hiyokosabrey:20210130112758p:plain

f:id:hiyokosabrey:20210130113034p:plain

今回ブループリントからこのマテリアルに干渉する方法として採用。

SceneDepthの値は、確認用(Buffer Visualization)だとグレースケールな見た目に変換されて表示されていますが、実際にはずっと大きな値になっています。

なので適当な距離をパラメータに掛け算(Multiplyノードの x4000)しています。

つなぎ方は変わりますが公式同様に割り算でも同じ結果にできます。

 

できたポストプロセスマテリアルを、使用しているポストプロセスに登録します。

テンプレートだと、World Outliner に存在してるので選択。

f:id:hiyokosabrey:20210130120702j:plain

Details タブの Renderring Features > Post Process Materials の項目から追加します。

複数のマテリアルがセットできるようになっているので、プラスボタンを押してフォームを出せば追加できます。

 

今回テストとして、レベルブループリントに以下のノードを追加。

f:id:hiyokosabrey:20210130121655p:plain

ゲームパッドの Face Button は、コントローラ右半分に並ぶ ABXYボタンのこと。

Left なので、Xボタン。ゲームパッドを使わない場合は適当なキーの Inputノードに差し替えを。

便利なタイムラインノードの中身はこんな感じ。

f:id:hiyokosabrey:20210130215549p:plain
調整しやすいように 0 ~ 1.0 でカーブを作っています。

これで できあがりです。

 

マテリアルでの計算で描画負荷が気になるようだったら、先にブループリントで計算してパラメータを更新するようにするといいかも。(マテリアルの掛け算はやめる)

このグラフで Depthに合わせた値にしてもいいし、ゲームによっては範囲を可変にしたりとか。

f:id:hiyokosabrey:20210130123137p:plain

レーマンを操作しながら好きなタイミングで発動できるので面白いです。

何かのスキル効果でゾーンに入った表現とかスキャン表現とかに使えそう。

表現方法をアレンジすると楽しくなりそうです。

レーマンではなくカメラからの距離なので、三人称視点よりは 、一人称視点の方が違和感は無いかな。

 

 

 

最近ちょっと気になるUI

原神のUIで気になったやつ。普段ゲームパッドでプレイさせてもらっています。

f:id:hiyokosabrey:20210129002431j:plain

フィールドに数か所、七天神像 という 回復拠点が設置されているんだけど、主人公以外のパーティメンバーは回復しかできないので、メニュー項目は基本↓この形。

f:id:hiyokosabrey:20210129003041j:plain

カーソルの初期位置は一番上『神像に奉納する』です。

上から2番目の項目『神像の恵み』を選ぶことでパーティメンバーの HPを回復することができます。

1番目の項目は、すでに最大まで奉納し終えたので、選択することはありません。

また、キャンセルボタンが無いので、『離れる』を選択しないとこのモーダルな状態から抜けることができない仕様です。

 

神像には 風神 と 岩神 の2種類が存在します。

肝心の主人公は、この世界の住人ではないので、特別にこの神像の持つ属性にスキルチェンジすることができます。

今のところ属性は 「風元素」と「岩元素」の2種類で、それぞれ「共鳴する」という風に表現されます。

プレイヤーが主人公を操作してこの神像に接触すると、メニュー項目が増えます。

f:id:hiyokosabrey:20210129004625j:plain

2番目に挿入されるのです。

もう一つややこしくなっている原因として、同じ属性の神像に接触すると、「~と共鳴する」という項目は現れません。パーティメンバーと同じ見た目になります。

つまり、チェンジが可能かどうかを判定して選択項目を増やしているのです。

 

いまだに、意図せず属性を変更してしまいます。ある意味トラップ的配置。

 

選択項目が表示されない理由が2つ

  • 主人公の属性が神像と同じなので、共鳴できない
  • 主人公以外だから共鳴できない

このため、思いのほかチェンジ可能な機会が少なくなり、回復を選択することに慣れてしまうのが要因だと思う。

 

ぼくがゲームのUIを設計するとに気を付けていることは、

  • 選択項目の数や位置(または順番)はよほどのことがない限り変更しない
  • 選択する頻度が高くローリスクなものほど、初期カーソル位置の近くにおく
  • 選択することで何らかのモードが変更される場合は初期カーソル位置から離す
  • 選択できない状態のものは、非表示ではなくDisable状態の見た目にする
  • このDisable状態の見た目でも、カーソルはスキップしない
  • リスクの大きな選択肢は端において目立たせる

 

とりあえず今回の事例に関するところでは上記くらい。

 

試しに Disable状態を入れるならこんな感じかな。

f:id:hiyokosabrey:20210130184016p:plain

「共鳴」そのものが主人公しかできないので、そこの納得度を上げるなら、主人公とわかる何かを入れてみるとか。

f:id:hiyokosabrey:20210130212741p:plain

「神像の恵み」がカーソルの初期位置だと嬉しい。

ちなみに「神像に奉納する」はMAXに到達してしまうと、選択肢としては不要になります。

これでかなり快適になるはず。

 

最初は慎重にテキストを読みながら選択項目を選びますが、そのうち、よく使う選択項目は、場所で記憶するようになります。ボタンを押す回数なんかで覚えていたりします。体で覚えるってやつです。特にリスクが低く、ポジティブな要素を選択する場合は特にこの傾向が強くなります。連打癖が付きやすいのも重要なポイント。

 

ゲームのUIは 呼吸をするように無意識でも操作できるように設計するのが理想的です。できるだけ安い学習コストで慣れてもらう。一度慣れたら操作に迷うことなく選択できるのが良いUIだと考えています。

 

とにかく デフォルト状態とイレギュラーな状態 が存在する場合、プレイヤーがどういった状況で認識するかによっては、ミスリードになりうるということを意識してUIを設計するように心がけています。

 

また、プレイが進んで、選択頻度に差が出る可能性のあるものや、特定の条件で追加されたり選択不可という状況の有無が判明していれば、開発段階でしっかり検討しておきたいものです。選択項目は並べ方にも開発の意図や姿勢が表れてしまいます。

 

原神はクロスプレイ対応なので、入力デバイス対応が相当大変だと思います。ぼくもワンタイトルで、ゲームパッド(複数)、タッチ、マウス&キーボードというマルチデバイス対応をやったことがあるので、大変さはよくわかります。そういう時はゲームパッド操作を基本に画面を設計するのをオススメします。マウスやタッチ操作にはカーソルポジションという縛りがないので、情報距離と操作回数の関係性をゲームパッドほど気にしなくても良いからです。

デザインはキレイだし楽しくプレイさせてもらっています。そのうちアプデが来て、イイ感じの 表示と操作感 になるかもしれません。その時は開発者がUIに対してそれなりの知見を得たということなのでしょうね。その瞬間を見届けられるくらいまではプレイし続けたいとは思います。

 

 

最後にちょっとした寓話

 

いつも多くのお客で賑わうラーメン屋さんがありました。

そして冷やし中華がメニューに加わる季節になります。

店主はあまり売れない自慢の冷やし中華を食べてほしくて、券売機の左上のボタンに冷やし中華を登録しました。人は左上に最初に目が行きやすいのをWebか何かの本で知ったからです。

すると定番のラーメンしか食べない常連客から間違えて押したと不満の声が・・・

 

またいずれ冷やし中華の季節も終わります。

店主はいつもの配列に戻しました。

次の夏、冷やし中華のボタンを空いているボタンに登録して、「店長のオススメ!」という小さなラベルを貼ることにしました。

おしまい

 

 

雑記::20210127

最近Twitterにあげたやつ

UE4 Ver4.26 でマテリアルノードに step 追加されたので使ってみた。以前のVerまではValueStep というノードがあって、それで代用していました。

f:id:hiyokosabrey:20210126230636p:plain

入力ピンの名前が Y と X になったので、仕様が分かりにくくなった気がします。

 

↓こちらのブログにとても分かりやすく解説されてるので気になった方はぜひ。

http://【UE4】マテリアルの「step」と「smoothstep」で遊ぼう!【★★】 | キンアジのブログ (kinnaji.com)

 

さっそく、よくある2重のゲージを作ってみました。

f:id:hiyokosabrey:20210125104801p:plain

カラーは格ゲーとかでよく見る黄色と赤の2色を、加算して作ってます。

 

f:id:hiyokosabrey:20210126231829p:plain

 

少し遅れて減る表現は、相手の攻撃でダメージを受けたことがわかるのと、食らったダメージ量がわかるので、食らっていい回数(あと何発耐えられるか)や、ガードの必要性、回復タイミングなどを経験として学習するのに便利な表現です。

f:id:hiyokosabrey:20210125104821g:plain

実装する方法としては、基本的に複数のゲージパーツを重ねることになると思いますが、今回作ったのは、カラーの加算ブレンドを使ってるので、表示するパーツは 1つだけです。

過去記事でも扱っていますがこちらは EventTick を使ってました。

 

limesode.hatenablog.com

 

今回は No Tick です。

キャンバスはImageパーツが一つだけ。

f:id:hiyokosabrey:20210126234501p:plain

上のマテリアルをセットします。

 

あとはWidgetブループリント。

 Float型の変数を2つ用意します。初期値は 1.0 で。

f:id:hiyokosabrey:20210126232844p:plain

ゲージは 0~100% で管理したいので 1.0 のときに満タン。Value がメインのゲージで、Delay が後から遅れて減るゲージ用。

 

 マテリアルのパラメータを更新する関数を用意。

f:id:hiyokosabrey:20210126233057p:plain

 

ダメージを受けたときに呼び出されるイベント。

f:id:hiyokosabrey:20210126233541p:plain

いったんメインのゲージからダメージを引き算して、ダメージ分を減らすイベントを呼び出します。マイナスになってしまったら強制的に 0 にする。

 

少し待ってからダメージ分を減らすイベント。

f:id:hiyokosabrey:20210126233722p:plain

0.02 ずつ減らしてゆきます。メインのゲージと比較して追いつくまで、Set Timer by Event ノードで、自身のイベントを繰り返します。

減るスピードは、減らす量が 引き算ノード で、減らす間隔が、Set Timer by Event の Time の値で調整できます。

Widget は以上です。

 

レベルブループリントで、テストします。

f:id:hiyokosabrey:20210126235029p:plain

 

用意するパーツが少ないし、マテリアルがシンプルなので時間をかけたくないときや、デバッグ的に仮アセットとして作るのにいかがでしょうか?

 

 

 

最近読んでる本

ジャケ買い というか 文庫カバー買い をしていた 山尾悠子の『飛ぶ孔雀』を読了。

「しんねりと燃え難い」という表現がお気に入り。

そんなに厚くないからすぐに読み終わるかと思ったら、飴のようにゆるゆると溶けるだけで口の中からなかなか消えない感じで、なかなかの読み応え。断片的に語られる場面、配管のようにどこへつながるかわからない緊張感、また走る列車の中から外を眺めているような遠近感、独特の雰囲気を放つ文体も相まってなんとも新鮮。 泉鏡花にも興味がわいてきました。

といいつつも、裏世界ピクニックのアニメ放映が始まったので、まずはこちらを読み進めています。

そういえば、実年齢より容姿が幼く描かれ、高い IQ さらに物言いがキツめのキャラというのは、なにかカテゴリ名でもありそうだけど、あるのかな?

 

 

ファミ通の不思議

毎週『ファミ通』を買っています。ゲーム界隈のトレンド情報はもちろん、興味の有る無しにかかわらずページを繰るたびにいろんなゲームのビジュアルに触れることができます。キャラクターのイラストも解像度が高いのできれいです。

ああこのゲームのコンセプトはこんな感じか~とか、キービジュアルのカラーはこの色使ってるのか~とか、このフォント使われてしまったな~とか、みんなこのカタチ好きだよな~とか、とにかく広く浅く俯瞰して眺めることができます。

コラム連載では桜井政博も面白いのですが西川善司の『ゲームのムズカシイ話』が特にオススメ。最新のグラフィックや映像や音響などの技術事情について分かりやすく解説してくれるので、未来のゲームを作るなら必読と周囲には言いまくってます。それにしても 伊集院光 は毎週休まず連載しててすごい。いつから書いてるんだろう。内容も読みやすいし。

 

そう 不思議 なんです。

どちらかといえば不可解?

読者投稿のページがあって、なかなか秀逸なネタも載るので楽しませてもらってますが、ここに採り上げられるネタで、「AV嬢」「スケベイス」「痴女」「童貞」などなどがあって、面白いんだけどなんかちょっと昭和の深夜ラジオの佇まいを感じてます。

ファミコン通信自体昭和発刊のゲーム雑誌ですし、当時から愛読されている方もいらっしゃることでしょう。とはいえ、最近はコンビニに置かない店増えてるし、DLコードが付いたりして、立ち読みもできなくなってます。そんな昨今においても読者コーナーにスケベイスのネタを投稿するのは、どんなペルソナなんだろうと思うわけです。

掲載されると ガバス がもらえて、既定の数が貯まると、Nintendo Switch やら PS4 などに引き換えられるので投稿に熱も入ることでしょう。毎週載る方や、複数のコーナーにネタが載る方もおられます。よほど編集者に気に入られたのでしょう。ひょっとしたら編集者の好みがAVやスケベイスなのを見抜いて投稿している方がいるかもしれません。

よく見かける投稿者の獲得ガバスを調べてみたことがあって、結構なポイントになってました。それでも投稿が続いているのは、ガバス目的ではないのか、実は編集者の誰かが・・・などといろいろ勘繰ってしまいます。ゲーム業界人しか買わなさそうなイメージもあるのですが、実際どれくらいがどういった層に売れているのでしょうか。個人的に買ってなくても、ゲームショップやオフィスなどの共有スペース、ロビーや待合所などに置いてあるかもしれない場合はそこでどんな情報交換が行われているのか気になります。

最近職場で机にファミ通を積んでいる人は絶滅危惧状態だし、周りに ファミ通 薦めても反応が弱いか、適当に相槌を打ってくれるケースがほとんどです。

とまぁそんなこんなで

読者投稿に情熱を燃やしているのはどんな方なのか、なかなか興味は尽きません。

オレキさん!わたし気になります!

 

 ではでは

 

 

 

 

 

 

ポップするリスト表示を試してみたのでメモ

3人称視点のアクションRPGとかで、フィールドに落ちている何かを拾うと、ログ表示のように画面端に表示されるあれです。

原神をプレイしてて作ってみようと思い立ったUI表示ですが目コピーではないです。

f:id:hiyokosabrey:20210106233401j:plain

試そうと思ったきっかけは、

  • VerticalBoxに追加した UserWidgetが、自身を Remove from Parent したらどうなるのか?
  • ガシガシ追加しまくっても、一定時間経過で勝手に消えてくれるのであれば、追加する側が管理しなくてもいいのでは?

 

という安易な推測によるものでした。

 

で実際にやってみた作り方をメモメモ。

 

Widgetを2つ使います。

まず最初に作るのは、表示する子要素であるWidgetから。

f:id:hiyokosabrey:20210104214201p:plain

 

UMGのキャンバスには、まとめてアニメーションさせるための CanvasPanel を追加して、あとはその子供として Image(下敷き用)、Image(アイコン用)、TextBlock(アイテム名など)を配置。

f:id:hiyokosabrey:20210104214320p:plain

f:id:hiyokosabrey:20210104214643p:plain

↑ Image_Cover は登場時に白くフラッシュさせるエフェクト用です。

 

最初から配置されている CanvasPanel は、Canvas Panel Slot を持っていなくてサイズを使ったアニメーションができないので放置。

 

ここでポイントが2つ。

1つは、余白を作っておくことです。
f:id:hiyokosabrey:20210104215511p:plain

画面に見せたいパーツ(中身)の大きさより、CanvasPanelを少しだけ大きくします。

これが並んだ時のスキマになります。

VerticalBox に追加する際に Padding で調整すると、Paddingの余白はサイズのアニメーションに含まれないため、タイミングによってはかカクっとなるのが見えてしまいます。

f:id:hiyokosabrey:20210104224334g:plain ← CanvasPanelに余白

f:id:hiyokosabrey:20210104224408g:plain ← Paddingで余白



アニメーションは、 Open(出現用) と Close(退出用) の2つ。

 

Open

f:id:hiyokosabrey:20210104232906g:plain


Close

f:id:hiyokosabrey:20210104233140g:plain

もうひとつのポイントはここ。

なるべくSizeのアニメーションは最後までとっておきます。

f:id:hiyokosabrey:20210104234459p:plain

先に Scale と Opacity で見えなくしてから、Sizeのアニメーションをさせるようにすると、リストに追加があったときに見やすくできます。

アニメーションで動きをつけるのは、気づきやすさ(視認性)を上げるうえで有利ですが、静止しないと読みにくい(可読性が下がる)ので、調整は大事です。

 

UIを試行錯誤しながら作っているこの状況で、気を付けたいのがこの視認性と可読性のバランスです。

テスト用の文字列やアイコン情報を表示しても、内容については仮のものなので、無意識に表示内容をスルーしています。動きや雰囲気に注意が向いている分、そこさえ良ければ、もう出来た感じがしてしまうという罠です。実装後の確認とチューニングはしっかり行いたいものです。

 

あと、細かいことですが、出現と退出のアニメーションを別々で作っているのは理由があります。

適切な表示時間を、ブループリントでDelay ノードで調整したいからです。

いい感じの表示時間が確定さえすれば、後でタイムラインを一つにできます。

また、表示時間の調整を行う際に、自分以外の方に説明するのが簡単です。

「なんか短くない? 何秒?」

「(Delayの値)1.25秒です」

「2秒にしてみたらどんな感じ?」

「ちょっと待ってくださいね」

てな具合にやり取りができます。

 

というわけでキャンバスはこのくらいにして、続いてWidgetブループリントを編集。

Event Construct

f:id:hiyokosabrey:20210104233602p:plain

右下のノード Remove from ParentSelf を指定しているので、自分自身が消滅します。

 

再生するアニメーションが 2つあるので

上の例では、アニメーション終了検知のイベント は使用しないケース、

下の例は使用するケース。

f:id:hiyokosabrey:20210105235540p:plain

 

いくつかの変数をパラメータとして受け取るようにしています。

f:id:hiyokosabrey:20210105003141p:plain

Expose on Spawn を有効にしているので、この Event Construct が実行される時にはすでにパラメータを受け取っているという段取りです。

f:id:hiyokosabrey:20210105005147p:plain

最終的に Structure にしたほうがよさそうな気はします。

 

表示のためのセットアップは、ブループリントのスクショがコンパクトになるようにマクロにしています。

マクロの外に接続するようにしているのは、自分以外の方、もしくは未来の自分がブループリントを見た時に、少しでも何をしているか、何をしようとしているかを解りやすくするための気配りみたいなものです。

で、マクロの中身はこんな感じです。

f:id:hiyokosabrey:20210105004145p:plain

FormatTextノード便利ですよね。

 

これで表示する子のWidgetは完成です。

 

 ここからは、リストを並べるためのWidgetを作っていきます。

f:id:hiyokosabrey:20210104214209p:plain

 

UMGのキャンバスには、VerticalBox が一つ。

f:id:hiyokosabrey:20210106000647p:plain

 

次にWidgetブループリント

f:id:hiyokosabrey:20210106001444p:plain

簡単なテストということで、変化を楽しむためのカラーを配列に仕込んでいます。

セットしている配列変数は、LinearColor型です。

 

カスタムイベントを用意します。

f:id:hiyokosabrey:20210106002142p:plain

CreateWidgetノードに、先に作ったリスト用のWidgetを Class としてセット。

f:id:hiyokosabrey:20210106003214p:plain

変数の Expose on Spawn を有効にすると、この CreateWidgetノード経由で初期値を渡すことができます。

 

これで出来上がりです。

 

 

あとは適当なレベルを作って表示テスト。

f:id:hiyokosabrey:20210106003758p:plain

Inputノードで、スペースキーを押すと、カスタムイベントを呼び出す。

 

f:id:hiyokosabrey:20210106011549j:plain

Twitterに動画を上げてるので、動きのイメージはこちらから ↓

テキストの表示が TextBlock のままですが、動きは同じになります。

 

一応検証用に、VerticalBoxの子要素をカウントしてみました。

キャンバスに TextBlock を一つ追加して、EventTickで監視した数を常時表示します。

Get Children Countノードを使って調べます。

f:id:hiyokosabrey:20210106011833p:plain

Remove from Parent で消滅するタイミングでカウントが減ります。

f:id:hiyokosabrey:20210106012210g:plain

いい感じに動作しているようです。

 

ガシガシ呼び出しても、勝手に消えていくんで管理する手間が省けていいなぁ、と思いたいけど、実際には表示数に制限が必要だし、制限を越えた分はプールしておいて、空きができたら、プールが空になるまで逐次追加し続けたりしないといけない。

とはいえ、最初の推測通りの結果になったので、よかったよかった。

 

というわけで

今回はこの辺で

 

皆様、健康でよい一年になりますように

 

今年もよろしくお願いいたします

 

雑記::20201231

2020年も今日で終わり、明日からは令和も3年ということで、1年間本当におつかれさまでした。このブログも開始から5年が経過しました。記事の数は181。ペースはのんびりですが、よく続いたなぁとしみじみ思ってます。いつも多くの方に閲覧いただいてて、それが嬉しくてとても励みになってます。ありがとうございます。

いろいろと気忙しい状況が続いてて、前回より間が空いてしまいましたが、ぼちぼちやっていこうと思います。

 

 

最近Twitterにあげたやつ その1

星のカービィ スターアライズのプレイ動画がタイムラインを流れてきたので見ていたら急に作りたくなったやつ。

f:id:hiyokosabrey:20201231000113j:plain

f:id:hiyokosabrey:20201231000231j:plain

f:id:hiyokosabrey:20201231000243j:plain

f:id:hiyokosabrey:20201231000253j:plain

f:id:hiyokosabrey:20201231000354j:plain

 場面転換で見かけるやつです。

テクスチャを使わずにやってみようと思って

f:id:hiyokosabrey:20201230235038p:plain

斜めに配置

f:id:hiyokosabrey:20201230235059p:plain

試そうと思ったきっかけは以下の3つ。

  • VectorToRadialValue ノードで円形のグラデが作れるよね
  • Step ノードで円の大きさが変えられるよね
  • UVってタイリングできたよね

この辺りが頭の隅に残っていたのがよかった。

 

途中計算がおかしくてなかなか粒がいい感じにならなかったけど、なんとかサマになってよかった。

SmoothStep を使うばジャギらないのが作れる。

 

あとは、波紋のように変化させたりしたくて、いろいろ試してみたけど、うまくいかず・・・。また方法をひらめいたらチャレンジしよう。

 

2021/1/20 追記 >>

このサンプルは、全画面にかける想定で、パラメータをなるべく減らしてConstantを使うことで気持ち的に処理を稼ぎたかったというのもあって、いろんなサイズの描画にはまったく対応できない作りです。都度マテリアルをいじるか増やすかしないといけないので、汎用性ゼロです。

ところが、ちゃんと汎用性があって、交互に並んでいて、グラデーション表現も可能になったのが紹介されました!

言及ありがとうございます!素晴らしいです > ネリスさん

lunanelis.hatenablog.com

<<

 

 

 

今年読んだ小説

普段通勤時間の暇つぶしのために少しづつ読んでいるんだけど、続きが気になってしまい家に帰っても読んでしまうほど。ハマったのが 知念実希人 の 天久鷹央 推理カルテ シリーズ。平積みで並べられているのを何度も流し見てるうちに、いとうのいぢ のイラストが気になってきて、ちょうど読みたい本が途切れたタイミングで手に取ってしまったのがきっかけで、表紙に惹かれたんだと思うけど、書店の推しに屈した瞬間だった。

というわけで出ている巻全部を大人買いして一息に読み切ってしまった。

 

ときおり挿入される主人公のモノローグのおかげで感情移入しにくいこともあるけど、ストーリーの流れ方がすごく好みだった。医療系ミステリは初めてなので、知ってるものから知らないものまでいろんな症例がトリガーになって起こった経緯を、ラストで鮮やかに説明してしまうところは、駆け付けた居酒屋で飲む最初のビールのような爽快感で病み付きに。著者が現役のお医者さまというか職業柄のせいか、病が人の心に与える影響や、また患者の周囲にいる人々にもメスをいれて、時に生々しく書かれる人間模様はさすがという印象。 個人的に医療への好奇心を満たせたのもよかった。

 

大好きな作家なのに、なぜだかずっと手を付けなかった 米澤穂信追想五断章 を読んで、感銘をうけた。リドルストーリーなるものに興味がわいたので 謎の物語/紀田順一郎(編) を読んでみたり、あまり長編は飽きるので、短編集や編集モノが多かったかな。最近気に入って読んでるのは、上田 早夕里。やっぱりSFは興味深い。

狐と鞭も面白かった。古典もいいな。

結構読んだ気もするけど、タイトルが思い出せるのは少ない。なんかもったいない。

 

若かったころ、敬語はもちろん丁寧語すら怪しかったので、語彙力を上げるために頑張って現代モノの小説を読むようになって今に至る。映像がないからこその楽しみ方があるのがわかったし、好きな作家にも出会えた。書店通いは楽しい。

VRの超巨大図書館とかできないかな。検索で探すのではなく、実際に背表紙を眺めながら歩き回れるような。本のタイトルや装丁から中身を塑像するのも楽しいですよ。

 

 

最近Twitterにあげたやつ その2

なんかマテリアルでビリビリエフェクトみたいなの、以前TLで見たような気がして、試してみようってなったやつ。

f:id:hiyokosabrey:20201231120126g:plain

テクスチャは 8x128

f:id:hiyokosabrey:20201231115836p:plain

カーブアトラスを作ってマテリアルで使う

f:id:hiyokosabrey:20201231115712p:plain

 

ノイズだけだと、全体に暴れるので、

f:id:hiyokosabrey:20201231131916g:plain

両端が0 のカーブを UV の V方向(縦)に対して掛ける

f:id:hiyokosabrey:20201231132311p:plain

f:id:hiyokosabrey:20201231132117g:plain

あとは、UMGにでも貼ればできあがり

f:id:hiyokosabrey:20201231132548p:plain

長さによってブレ幅が変化するので、マテリアルのほうでいろいろ調整が必要だけど、ゲージに乗せると、スタン中の表現として使えそう。

 

 

というわけで

この年末も何かゲームUIネタを書こうかと思ったりしたのですが、うまくまとめられず結局筆が進みませんでした。

以前から携わってたタイトルが、春にリリースされて腑抜けていたのもあるかも。(長いな)

 

レンタルオフィス借りて勉強会~と思ってた矢先での新型コロナ大流行。来年はどうなるのでしょうか・・・まぁいろいろ安全な方法を探っていきたいところです。

 

相変わらず記事のネタは常に探しているところですので、このブログのコメントか、Twitterでも提供いただけると大変助かります。

このゲームのこのUIってどうやって作ってるの?とかももっと書いていけたらなと思ってます。

 

ペースは気まぐれでゆっくりですが

今後ともよろしくお願いいたします。

 

ではでは 皆さま よいお年をお迎えください

 

文字がシャッフルしながら出てきてランダムに消えていくやつについてのメモ

さすがに涼しいと言ってられないほどの気温になってきました。ほんの数日でしたが大好きな稲刈り後の田んぼの匂いと金木犀の香りで秋の深まりを実感している今日この頃です。

 さてさて ちょっと間があいてしまいましたが、先日Twitteにあげたテキストエフェクトについて書こうと思います。

 

 

今回のはブループリントは載せずに、どういった構造にしたかをメモします。

多分もっといい方法がありそうなのと、実際の需要としてはニッチすぎるので、BPの組み方やら、UMGの作りはまず参考にはならないだろうという想定です。

 

ということで、まずはシャッフルしながら文字列がでてくるやつ

 

初めに考えたこと

1文字分だけ表示するWidgetを作ってそこでランダム処理をさせる方法。

ある文字列をバラして、1文字づつをWidgetにシャッフル時間と共に初期値として渡して並べるだけというラクな発想。

f:id:hiyokosabrey:20201029230537p:plain
フォントの選択肢が多いのと、放置プレイできて便利なんだけど、文字数が多くなると、それだけWidgetの生成と消滅が発生するので、ちょっと負荷が心配になるので却下。あとレイアウトも考慮すると管理するWidgetの階層が増えそう。

 

そこで、TextBlock ひとつのままでシャッフルできないか考えてみた。

f:id:hiyokosabrey:20201029230556p:plain

要するに文字列の段階でいかにしてうまくシャッフルの文字列を作るか。

さらに、

  • シャッフルが始まって全部が一斉に止まるのはやりたくない
  • 少しずづ確定させたい
  • 端からではなくランダムに

というのをハードルとして課すことにした。

 

 

あらかじめランダムな文字列を作ってしまえばいいのでは?

文字列を受け取ったら、その文字数分のランダム文字列を先に作り置きして、あとは順番に取り出して表示するという方法を思いついた。なんかよさそう気がする。問題なのは、どうやって少しづつ確定させるか。

年々しぼんでいく脳みそで頑張ってみた結果、配列を使うとうまくいきそうな気配を感じたので試してみた。

まず文字列を配列にバラせるかどうか ノードを漁ってみるといいノード発見。

f:id:hiyokosabrey:20201029232144p:plain

 

String型の配列を用意して、文字数分の要素を確保。

 

f:id:hiyokosabrey:20201030002021p:plain


ここに、ランダムな文字をランダムな文字数ぶん入れて、最後に表示する確定文字で埋める。

配列の各要素に入れる最大文字数は演出時間で調整するとして全部一律。

最大文字を14とした場合。

 

f:id:hiyokosabrey:20201031155422p:plain


紫色の文字がランダム文字、青色の文字が確定文字。

ヨコが配列の要素、タテが要素内に並べた文字列。

あとは表示する際、先頭から順番に取り出して、くっつけて表示する。

f:id:hiyokosabrey:20201031155403g:plain

 

表示してみるとこんな感じ

f:id:hiyokosabrey:20201031161322g:plain

思ってた感じにできた。

 

ランダムと言っても、ある程度幅の調整は必要。

f:id:hiyokosabrey:20201031161617p:plain

ランダム文字の生成は、固定の文字列から一文字を抜き出す方式。

f:id:hiyokosabrey:20201031162554p:plain



 

消えるときもランダムで虫食いっぽく消したい

ランダムの欠点というか残念なところは、同じ数を引いてしまうことがあるとこ。

ランダムに位置を決めたら文字が空白かどうかチェックして、空白じゃなければ消す。空白だったら、再びランダム位置決め・・・ これだと終盤空白だらけになった時、空白じゃない文字を引く確率が下がってしまい、最後まで消えきる時間が不安定になってしまう。

そして思いついた方法が2つ。

一つは、表示している文字がアルファベットと数字だけなので、順番に検索をかけてヒットしたら消すことにすると、確実に一定の時間内ですべて消える。

確実に消えるけど、”WWW”みたいな文字列があると、一斉に消えてしまうのと、法則性が見えてしまいそうなのが無粋かな。

 

でもう一つの方法が、文字列の中で消す順番をランダムにする方法。

順番を決定するための配列を増やすことで対応できそうということで試してみることに。

まず表示している文字列と同じ数の要素を持った配列を用意。

そこへ、0~ 順番に数値を入れていって、最後にシャッフル。

 

f:id:hiyokosabrey:20201031170149p:plain

 

配列の要素をシャッフルしてくれるのがこのノード

f:id:hiyokosabrey:20201031170131p:plain

 

この配列の要素を順番に取り出しながら、表示している文字列を空白に置き換えていく。

文字列操作のノードを駆使してなんとかこんな感じでできた。

f:id:hiyokosabrey:20201031170643p:plain

Leftノードは、文字列の左から指定文字数ぶんをゲット、同様に Rightノードは文字列の右から指定文字数ぶんをゲット。

該当する場所の文字をよけて、切り出すイメージ。

f:id:hiyokosabrey:20201031172632p:plain

 

これで、配列の要素数ぶん(=文字数)この処理を繰り返せば確実に毎ターン一文字ずつ消えていくという寸法。

 

f:id:hiyokosabrey:20201031173653g:plain

 

これで出来上がり。

 

↓これは、Twitterに上げたGIFで 30fpsで撮ったもの。

f:id:hiyokosabrey:20201031173923g:plain

 

一応満足いく形にできた。

 

でもしばらく眺めているうちに 確定したタイミングでもう少しメリハリが欲しいかも、と思ってカラーで変化をつけてみた。

 

f:id:hiyokosabrey:20201031190654g:plain

ビビリだけUMGのタイムラインで、出現時と消滅時は、Lerpノード を使ってるので、文字数によって時間の長さが変わっても大丈夫なつくり。

 

 

とりあえずこれで良しとしよう。

ランダムとうまく付き合うのは、なかなか骨が折れるというか、神経を使う感じですが、UI表示でランダムを使えると楽しいので、頑張ってしまいます。

プログラマーに指定書で細かく書いて渋い顔されて、いざ画面に表示されてからさらに微調整するといった面倒に突き合わせて申し訳ない気持ちになったな時代は遥か彼方。

いい時代になったもんです。

もっと効率のいいやり方とか、賢いやり方があると思うので、共有してくださる方が現れるのを期待して、この記事を書いています。

 

映画の冒頭やアニメのオープニング、ボカロのMVとかで面白いテキスト表現に出会うとうれしくなります。と同時に先を越されたような口惜しさも味わうことになります。

ゲームは動画ではなくリアルタイムで描画するので、インタラクティブな見せ方ができるのが魅力の一つ。映像作品を参考にしたりUE4でいろいろ実験して、テキスト表現のネタを引き出しにしまいつつ日々精進してまいりましょう。

 

ではでは

ステキ な テキストエフェクトライフを!

 

 

雑記::20201011

Twitterだと書ききれない、ブログだとボリュームが少なめの内容で書き散らしました。内容は適当なのはご容赦いただけますと幸いです。

 

 

ここ最近風邪っぽくて

いつもと同じものを食べてるのに、あれ?こんな味だったっけ? と、ちょっとした味覚の変化にびくびくしながら過ごしています。 新型コロナじゃない普通の風邪?従来の風邪?だったとしても、大変不安な気持ちになるので早く免疫をゲットしたいですね。昔だったら誰かの祟りとか怨霊の仕業で必死に鎮めようとしただろうな。陰陽師という職業が今も続いていたら、この疫病の原因はなんと答えるのだろうか。などと資料を読みながらいろいろ妄想しています。

 

 

最近『原神』始めました

おすすめポイントはどこかと聞かれれば、景色が綺麗なのとキャラがかわいいのと、あとはそれくらいだったりするのですが、ブログの記事を書かなきゃと思いつつも原神始めてしまうくらいのおすすめ感です。で、コントローラ操作で遊んでいるのですが、ボタン操作のナビ表示をしっかり見てから操作しないと意図しない結果になるので、かなり学習コストが高い印象です。慣れの問題でしょうけど 日系プレステ操作の 〇決定 ×キャンセル のボタン配置がそのまま XInput系ゲームパッドで、B決定 Aキャンセルなのが辛い。

f:id:hiyokosabrey:20201009012426p:plain

ゲーム中のナビ表示に従ってきた経験で決定やキャンセルをボタンの場所だけでなく文脈(でいいのかな?)で体得しているのを改めて実感。

Nintendo Switch版 はまだリリースされてないけど XInputと逆なので、たぶん今の仕様でも問題なさそう。

f:id:hiyokosabrey:20201009013145p:plain

 

先日公開されたPS5 の仕様も考えると、マルチプラットフォームや縦マルチ対応でこの辺りを開発される現場の方々の苦労を想像するといろいろこみ上がるものを感じます。

『原神』を遊んでいて気になるのは、UIの操作ナビ表示に頼りすぎててボタンの役割をうまく設計できていないところ。細かい話になるのでこの辺はまた別の機会に譲るとして、ゲームパッドにやさしい作りになってない印象を受けてしまうんだけど、今後どこかのタイミングで対応が入るのかな。

 

 

UMGでヒット&ブローを作ってみた

作ったといってもNintendo Switchアソビ大全に収録されているゲームをUE4で再現しただけです。マスターマインドっていうかなり古いボードゲームがあったよな~となんとなく記憶の隅にあった程度で、いざ遊んでみるとこれが結構面白い。ルールはシンプル。隠された4つの色と順番を当てるだけ。CPUの思考とかもいらないし、ほぼほぼUIだけじゃん、て甘く考えてUMGで作ってみたわけです。できたのはこんなやつ。

f:id:hiyokosabrey:20201010100753j:plain

あとでブログの記事か、UIプロトタイプの教材にできないかな~と考えながら作ったので、あえて仮素材感バリバリです。

Widgetの切り分けとカーソル制御、判定部分で悩みましたが、なんとか遊べるとこまでできました。記事読みたい人いるかな?

 

このゲームは基本的にゲームパッド操作に向いていません。それをちゃんと遊べるようにしているのがさすがNintendo。そこに感心したのが今回作ろう思ったきっかけでもあります。とはいえ問題点がまったくないわけではなく、Joy-Conで遊ぶ時アナログスティック操作で動かしたくないほうのカーソルを動かしてしまい慌ててしまうこと。

 

UIの仕様はだいたい以下のとおり

 

  • 移動方向の違うカーソルが同時に2つ存在する
  • 中央縦に並んだ4つの穴すべてに、画面下の横に並んだ6つの選択肢から選んでセットする
  • 4つ埋まると判定可能になり、OKボタンが出現
  • 判定結果をテキストと4本のピンで知らせる
  • 左端から順番に判定していく
  • タップ操作も対応(今回の検証では無視)

 

で、作っていて気づいたことがあって、

一つセットすると、カーソルが次の穴に移動するかしないか。というもの。

ただ遊ぶだけだったらきっと気づけなかったと思う。

本家では自動で次の穴にカーソルが移動します。

文字入力の際にキャレットが移動するのと同じ感覚。

ところが自分で一から作っているものですから、ちょっとずつ作りながらテストします。まずは自動でカーソルが移動しない状態ができたので、遊んでみたところものすごく遊びにくいことに気づいたのです。

おそらく原因は、カーソルが2つあって独立して操作しなければいけないところ。

  f:id:hiyokosabrey:20201011102637p:plain

気持ちは次の穴に向かっているのに、カーソルは動かない。次の色も選ばなくちゃいけない。これがそこそこ気ぜわしくなって、操作の順番がおかしくなることがしょっちゅう起こりました。バグ取りしつつ何度か試すけど頭が慣れてくれない。で、ようやくインクリメント(でよかったかな?)処理を入れたら、なんということでしょう!とりあえず4つすべて埋まるまでは色を選ぶことに集中できて快適になりました。

こういうのは、デザイナーがあれこれ考えるより先に、プログラマーが先に解決してくれてたりするので、今回気づけたのが妙に嬉しかった。

 

そういえばこれに近い感じのゲームがあったのを思い出しました。

ナンプレです。数独とも呼ばれますね。あれは9x9マスの移動に方向キーを全部使うので、このヒット&ブローのような操作で混乱することはない。ナンプレも結構好きで自作したこともあるのですが、よく見かけるのがミニポップアップ方式。ヒット&ブローだとこんなイメージかな。

  f:id:hiyokosabrey:20201011104324p:plain

これだと上下移動と左右移動が同時にはできなくなるので、操作が混乱することはなくせます。ではなぜこれを採用しなかったか?

おそらく、画面下に選択リストを配置しているせい。ただしこの存在価値は非常に高いと思われるので、費用対効果を考えて残したのだと思います。推測ですが、

 

  • 画面がにぎやか(穴がいっぱいあるだけなので、このゲームの場合重要)
  • 選択肢(=出題の範囲)の数がわかる
  • アナログゲームの趣き=コンポーネント(駒とか)の手触りをイメージ
  • 操作しているより考えている時間の方が長い

 

あたりかなと。特に2番目の選択肢の幅が明確なのは、思考するときに重要な要素。

これは試してないですが、実際に作りながらだと検証できますね。

 

このカーソル送り機能は実際に試してみて気づくことができました。この感覚を共有したいのですが、文字で伝えるのは難しいです。ということで、ゲームUIデザイナーの紳士淑女の皆さんにはぜひともアンリアルエンジンでプロトタイピングを嗜んでいただきたいなと強く心に思った次第です。

 製品になったUIは、開発者の試行した結果が結晶化している状態なので、直接本人から聞き出さない限り、どうしてそうなったのか?という理由は推測するしかなく、真相は藪の中。

一から自分のUIを作れるようになるには、デザイン力と情報設計力は大事だけど、何より説得力がカギ。ロジックは問題ないようにしてやるからデザインは任せろ、と言えたらどんなにカッコいいか!とはいえ、仕様変更なんて世の常。諸行無常の響きがこだましています。どんなデコレーションにも対応できるロジックが自分の中にないと、デザイン変更に耐えるのはかなりしんどいものです。そこで体験として持っていると、UI提案する際に戦力アップ間違いなしです。

そこに遊び心が加わるともう一気にUIクオリティが上がります。

というわけでちょっと大げさに盛りましたが、実際作ってみたらこうだったという気づきは、できれば日常的に経験値上げしていきたいなと思う今日この頃。

 

 

オーバーロイドが楽しい

人に話すと大抵ラノベオーバーロードと勘違いされるのですが、アナログのカードゲームです。

OVERЯOID と書いてオーバーロイドと読みます。2人で対戦します。13枚のカードしか使いません。カードの役割を覚えるまでは、リストを作ってみながらやるといいです。

ルールは超シンプル。一枚づつ出し合って数字の大きいほうが勝つというもの。そこにカードごとの効果が加わることで、より複雑な心理戦が繰り広げられます。自分の持っていないカードを相手が持っていることにはなるので、読みやすいと思いきやそう簡単には読めないのがこのオーバーロイドの真骨頂。6枚づつ配って1枚残った伏せ札。これがまた悩ましい。とにかく確実に勝てるカードが一枚もないのです。たった13枚しかないのにこの凝縮された感じ。勝敗がついた後の感想戦もまた大変楽しく盛り上がります。数字と役割とのバランスが絶妙で、シンプルなのに同じ展開にならない奥深さ。

とてもよくできているので、気になった方は是非一度遊んでみてほしいです。

 

オンラインでした手に入らないみたいなので、すぐに試せる簡単な方法をご紹介。

トランプの A~K までの13枚を用意。

あとは、公式サイト にルールも載っています。カード効果 も載っているので、これを見ながらでも十分プレイできます。

イラストもカードのデザインも素敵で、楽しみ方がわかれば本物のカードを手に入れて遊ぶと雰囲気が出て盛り上がること間違いなしです。

 

 

バリウムがおいしく感じた

火曜に年一回のドック検診受けてきまして、珍しく空腹だったせいか、バリウムを飲んだ時に、ああ、これが食べ物だったら・・・と悲しくなるくらい美味しくいただきました。空腹感すげぇ。バリウムはお腹に溜めておくと危険と脅されるので、出し切るためにゴハンに申し訳ないと思いつつドカ食いする。今年は検査会場の近場で使える食事券をくれた。有難かったけど、このお金はどこから出ているのだろう。

 

 

UMGの最適化の話

この記事を書いているときにTwitterに流れてきたこれ

 

興味深いことを紹介してくれていてうれしい。特にSMeshWidgetのパーティクルは面白いですね。Mapのアイコンのような大量の表示パーツがある場合などに効果的って話で、ぜひ将来のVerで使えるようにしてほしい。

負荷軽減のテクニックで、Tickをなるべく使わないとか、Visibility設定の Hiddenよりは Collapse の方がいいよ とかはそれなりによく聞くやつだけど、ツリーの平坦化、階層を深くしすぎないというのと、HitTest しなくていいものは 無効にするというのは、確かに!って思った。

Widgetの生成はコスト高いので、プールして管理する方法はそれなりに考えたりします。たとえばフェードインアウト用のWidgetや汎用のダイアログなんかは、常駐させる方が何かと都合がいいし。表示頻度やタイミングなんかを相談して決める感じ。

 

 

 

 

 

今回はこの辺で

 

みなさま お体大事になさってください

ではでは

 

 

 

 

 

 

 

 

 

 

 

 

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

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

前回の続きです

 

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

 

ではでは

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