去年の6月から書き始めてもうすぐ一年。のんびりな更新でようやく80本の大台に乗りました。この企画が世の悩める UI開発者様へ少しでも助けになれば幸いです。
今回は、見た目9スケールのようですが、テクスチャを使わないでフチドリを作ります。最近見たゲームで記憶してるのはスト6ですね。体力ゲージが重要な要素である格闘ゲームにおいては『顔』みたいなものです。ゲームの性質上 60fpsを死守するためにUI表示にかかる描画処理も相当シビアなはずで、たくさんの試行錯誤や工夫がなされたのだろうと想像しています。
描画の方法が同じかどうかわかりませんが、シェーダーで作ることができます。
テクスチャを使わないほうがシンプルに作れるので、2本だけ紹介しようと思っていましたが、一応テクスチャを使ったのも参考用に追加で作りました。
ゲージの長さを変える方法は、おおまかに分けて2つ。
ひとつは表示サイズを変える。もう一つは表示サイズを変えずにシェーダーで塗分けたり削ったり。
今回のフチドリは、ゲージの長さが変わったときに、グラデーションの幅を維持する ことが重要になります。
アンリアルエンジンのUMGでは表示サイズを変える方法がいくつかあります。
各種Panel系に依存するタイプと、Render Transform の Scale を使うタイプがあります。
Panelに依存するタイプは、相対的なものと絶対的なものがあります。
Render Transform は、シェーダーの計算が終わってからのスケーリングになるようなので、伸び縮みすると、グラデーションの見え方に問題が発生します。

上段が、Size X を、下段が Scale を使って短く(30%)した状態です。
3倍の長さにすると↓図のようになります。

今回 フチドリの幅を安定させるために TexCoordノード の Coordinate Index 3 を使います。

画面に描画しているサイズを取得できるので、縦と横でフチドリのバランスを調整するのに使います。
Render Transform の Scale では、表示サイズを TexCoord[3] で取得できないので、Scale を使わないようにします。
80. フチドリ(内側)

UV空間をグラデーションとして扱います。
まずは上下左右を反転したUV空間を作ります。

定番のやつです。

U と V それぞれ 中央が 0 、端が 1.0 です。
フチドリの幅(太さ)は、比率で扱います。
U方向とV方向それぞれの端にグラデーションが存在することになるので、例えば 表示サイズ 256pxの長さに対して 8pxの幅を想定するなら、フチドリは端同士を合わせて16pxということになります。

この計算が以下。

16÷256= 0.0625
小数の桁が多くなったので、わかりやすい値 0.1 で図にしました。

ここからフチドリの幅(0.1 + 0.1 = 0.2) を 1.0 から引いた値(1 - 0.2 = 0.8)で引き算します。


中央がマイナスの値になっているので、Clampします。

さらに フチドリの幅を比率にした値で割る(0.2 / 0.2 = 1)と ようやく 0~1 になります。


ここで、U と V を ComponentMask でいったん分離。
Maxノードで合成すると、四隅が 額縁のような状態になります。

Lerpノードで着色したら出来上がり。

長さを変えてもフチドリの幅が一定になります。
81. フチドリ(内側) その2

80と似ていますが、アプローチを変えてみたのがこれです。

フチドリの幅を Stepノードで決定しています。
グラデーションの幅をフチドリの幅に調整するのではなく、ゲージの中央を0、端が1 になるようにしています。
U方向だけは伸び縮みしてほしくないので調整します。

(中央の黒い部分が多いように見えますが sRGB の補正がかかっています)
このグラデーションを作るために、1-x ノードが 2回登場するあたり、ちょっとムズムズしますね。
まだ効率のいい計算方法がありそうな気配はしますが今回はこの辺にしておきます。
グラフにするとこんな感じになります。
表示サイズ 横:縦 の比が 10:1 だったとします。
10倍するとこんな状態。

1-x すると

マイナスの領域は Max ノードによって使われないので、結果的に 0 ~ 1 の部分だけが使われることになります。Clampする必要はなくなります。
Max ノードは A と B を比較して大きいほうを採用します。
グラデーションの幅が大きいので、Step か SmoothStep で絞ってから着色します。
次はテクスチャを使ったやつ。
82. フチドリ(内側) その3

テクスチャは、表示サイズに合うようにサンプリングされ描画されます。
表示サイズに合わせるようにUVを調整してやるといい感じになりますが、ちょっと計算が大変そうです。なので シンプルにUVを移動させてゲージの長さを変える方法を採用します。38. で紹介した方法です。

計算はシンプルなのですが、パーツが2つあるので、そのUVを切り出すのにノードが増えました。
フチドリの幅はテクスチャ側で調整するので、Texcoord[3] を使わなくても作れます。
使用したテクスチャは 512x64px のサイズ。
画面に表示する大きさを 256x32 として想定しています。

ゲージを削るのがアルファチャンネルの役割。

パーツとしては 上半分がゲージの主要部分。
このブログの背景に溶けるので、わかりやすくなるように着色しました。
![]()
カタカナの コの字形に左端を開けてグラデーションが配置されています。
U方向に移動させるのでその分のスペースを右半分に確保してあります。
下半分が ゲージ左端のフタみたいな部分です。
![]()
移動はないのですが、ゲージの長さ分を切り出すので空いています。
結構もったいない感じはしますね。
表示したいゲージの長さ次第ですがタイリングの設定を Wrap から Clamp に変えるとかなり節約はできます。
サンプルのゲージの長さを 256px にしてしまったので、Clampするための余白がなく、仕方ないので 512px まで伸ばしました。最近はべき乗じゃなくてもいいんですけどつい癖ですね。まぁテクスチャでもフチドリ表現ができることを紹介できれば目的は達成です。
今回は以上です
そんなに目を引くほどのものではないですが、簡単にできそうに見えるけど、いざやってみると簡単ではないタイプです。
え?ゲージの長さが変わっても、フチドリの幅が一定!? どうなってるの?
こういった不思議に気付けるかが結構大事だと思います。対策したくなる、思わず方法を探ってしまう、という方はすでにTAか、TAに向いているひとかも。
シェーダーだけで頑張ってみたり、テクスチャをうまく利用してみたり、いろいろ試すことで新しい発見があるかもしれません。このフチドリ(内側)については他のアプローチがありそうなので、ぜひ探してみてはいかがでしょうか?
ではでは
素敵なゲージライフを!