今年も新人さんたちが入社してきました。去年のこの時期はいろいろとアレやコレやでもう大変でしたが、新型コロナに気を取られてもう一年が経ちました。早いものですね。まだまだ脅威は去っていないというかむしろ近づいてきてる気がするので、戦々恐々とする毎日です。UE4でもいじって心を落ち着かせるとしましょうか。小ネタですがブログに残しておきます。
最近Twitterにあげたやつ その1
グレイマンを特訓するための体力ゲージができた pic.twitter.com/5CN7bFJL0x
— みつまめ杏仁 (@MMAn_nin) 2021年4月11日
あの最近話題の育成ゲームです。ついアニメも観てしまい、涙腺対応でティッシュの山を築きながら作りました。
最初『春のゲージ祭り』というお題で記事を書こうと思っていろいろ準備していたら、いつの間にか体力ゲージができていました。マテリアルを使ったゲージで、なるべくパーツ数を抑えていろいろ表現できないかと模索しているところだったので、さっそく参考にさせてもらうことにしました。
マテリアルでいろいろやりすぎるとGPUの負荷が心配にはなりますが、ゲージなので面積は大きくはないし、表示するパーツ数を増やさず情報量を増やすことができるので、結果的にオートレイアウト的な処理が減ります。もちろん実機で負荷検証するのは必須なんだけど、よいこは真似してみてね。
マテリアルはこんな感じ
予想値 と 現在値 をそれぞれ Step で 0 と 1 に分けたものに、0.8 と 0.2 をかけてます。
足し算して 1.0 になればOK。
これを Lerp ノード に渡すと、濃淡が表現できます。
1.0 のところは、グラデーションがそのままで、 0.0 のところは ベースのカラーが、 0.2 のところは線形補間(Linear Interporate)された状態になります。
これで、特訓によって減少するであろう未来が表現できた。
次は増加するときの見た目。
加算と減算で条件分岐、とかやりたくなかったので、
予想値 と 現在値 の差分を 計算に利用します。
これをゲージ本体のカラー(グラデーション)の底上げに使います。
加算するといい感じになるように底上げ具合を調節。
予想値が下回った場合は減算になります。
マイナス値をどうにかしないと、ということで登場するのが clampノード。
clampノードは 指定した範囲をオーバーした値はカットします。
正確には、 Min を超えれば Min の値、 Max を超えれば Max の値になります。ノードのデフォルトが Min = 0、 Max = 1.0 なので何もつないでませんが、ゼロ以下の値が入ってくると、しれっと 0.0 を返します。
回復分のカラーに 常にこのclamp後の値を掛けてるので、加算のとき、減算のときで、2種類の状態を作り出せます。
掛け算と足し算だけでもこういった条件分岐みたいなことができるので、面白いですね。
掛け算のこの3つパターンを押さえておくとイイことあるかもよ。
0 × 0 = 0
0 × 1 = 0
1 × 1 = 1
掛け算に ゼロ が入ると問答無用で ゼロになります。
また、イチ を掛けると何も変化しません。
この辺をうまく組み合わせて作っていきます。もし触るのをためらっているUIデザイナーがいらっしゃるなら、UI表現の幅も広がるので、恐れずにぜひいろいろ試してほしいです。
せっかくなんで増減するアニメーションを作ってみました。
ブループリントでは、ゲージのImageにセットしたマテリアルを、Dynamic Materia lInstance として変数化しておきます。これを使ってマテリアルにアクセスします。
予想値をもらって反映するイベント(または関数)も用意。
マテリアルのパラメータをセットする関数はこんな感じ。
今回 Float型の変数は3つ使ってます。
増減のアニメーションは Set Timer by Eventノードで。
やりたい仕様がうまくできるとパズルが完成したような心持ちがします。
と思いつつも、ゲームをプレイしながら増減するときの動きをよくよく観察していると、重ねて処理しているように見えるので、今回のつくりは完コピにはならなかったけど、いろいろ検証できたので面白かった。
最近Twitterにあげたやつ その2
HorizontalBox で〇れ味ゲージができた
— みつまめ杏仁 (@MMAn_nin) 2021年4月14日
サイズが比率で指定できるので扱いやすいかも#UE4 #ue4UMG pic.twitter.com/AorF62WHKo
ふと思いついて試してみたシリーズ。
この 〇れ味ゲージは過去記事でやってまして、当時はマテリアルを使いました。
limesode.hatenablog.com結構ややこしいことしてましたね。
今回は HorizontalBox を使います。マテリアルは一切使用しません。とてもシンプルです。
HorizontalBoxをひとつ、子供として色のついた Image を入れます。
HorizontalBoxの子になると、親のタイプに合わせて Slot が変化します。
Size の値を変更すると、幅が変わります。
すべての Sizeを 1.0 にすると、すべてが等幅な状態になります。
ぴっちりと隙間なく自動で調整してくれるので、個別にSizeをいじってやれば棒グラフ完成です。
可変しなくて固定の棒グラフならこれを量産して、表示を切り替えるだけで使えそうです。でもやっぱりスクリプトから制御したいですよね。というわけで・・・
まずは、Size を適用する関数。
Get Child At ノードは、 HorozontalBox の 子要素を、Index番号でアクセスできるようにするノードです。
下の Make系 ノードは単体で検索するより、この場合、右上の Set Size ノードの左のピン In Size からドラッグするとすぐ近くに見つかります。
Float型の配列を一つ作って、適当な値(テスト用)を入れます。
配列の数は HorizontalBox の Image と同じ数。
これを計算して比率を求め、上の関数で適用します。
いったん全部足して最大値を求め、それで割ることで一つ一つの割合がわかります。
LastIndexの値は一応 引数として受け取れるようにしてます。
テストだったら固定値を入れたつくりでも問題ないですが、こうしておくことで、一度できたこの関数を編集する機会が減らせます。結果調整の手数が減ります。
グラフの表示を更新するイベント(または関数)
ゲージ全体の長さは 0~1.0 で受け取る仕様。500は実際に表示する最大の長さ。
ゲージの長さを実際の表示幅で受け取る仕様だと、デザインやレイアウトの変更でゲージそのものの長さを変更する際に大きな問題となります。パラメータを管理する者と、デザインを管理する者はおそらく別々だろうと思うので、なおさらこういった配慮はメンテナンスのコストを下げる効果があります。
できあがり。
グラデーションのテクスチャ作って Image にセットすると見た目を少しアレンジできます。
文字でも世界観を
遊んでいて最近気づいた。
基本的に『馬』の表記を「ウマ」「バ」と回避しつつも、「有馬記念」だけはどうしようもなかったんだろうな。『有マ記念』・・・『アリマ記念』
で、結果フォントのグリフいじってるようですね。たった一文字、この一文字を加工するだけで、このフィクションな世界のリアリティを感じさせてくれる心遣いがステキすぎる。
外字として追加するのが簡単だしコストが一番安くできるんだけど、置換が必要になるうえ、テキスト管理のコストや置換漏れの確認工数なんかがパないので、おそらく馬(U+99AC)のグリフそのものをいじる方が安全ということだろうと思われる。自分だったら確実にそう提案する。TextMeshPro(埋め込まずにAtlasを使用する方)使ってるんだったらマージしてるかもしれない・・・?
フォントベンダーの名前が見つけられなかったんだけど、オリジナルフォントじゃなければそれなりにコストと期間は支払っているはずで、それでもやってやろうという開発スタッフの愛と意気込みに感服です。さすがに馬偏の漢字はいじってないみたい。
ではでは
今回はこの辺で
誰かの何かに役に立てれば幸いです