ほんと暑いですね。アイスコーヒーがおいしい。希釈用のリキッドは濃さを調節できるので、氷をたっぷり入れて水は少なめ。ゆっくり溶けていくのをちびちび飲んでます。
さてさて
UEでは マテリアルインスタンス というアセットがあります。
マテリアルを継承し上書き用のパラメータを持つアセットで、派生形を効率よく作り出すことができます。
UIで利用する場合、シェーダー内のパラメータに対してBPから 動的 にアクセスするケースが多い印象です。また、パラメータの値がセンシティブな場合やテクスチャアトラスの内容が変動しやすい場合、デザイナーに調整を任せてしまった方が作りやすい場合があります。そういった場合にパラメータのバリエーション管理をBPで行わず、マテリアルインスタンスの形で 静的 に用意することもあります。
今回は、シェーダー(UEではマテリアルと呼ぶ)を作って、パラメータ違いのバリエーションでゲージを作ります。
構成としては、ゲージ部分とおまけのアイコン部分とで、2つのシェーダーを用意します。
また ゲージとアイコンという違う要素で同じパラメータ(ゲージ量)を扱うので、マテリアルパラメータコレクションを利用します。
この企画を始めたときにMaterialParameterCollection アセットについて触れていますが、便宜的なものだったので、単にこの企画用に使ってますよ~、実装で使うぶんにはScalarParameterノードでOK、みたいな書き方でした。
今回は仕様として必要なので、作成方法について書いておきます。
コンテンツブラウザの空いているところで、右クリックするとコンテキストメニューが出てくるので、 Material > Material Parameter Collection を選択します。

↓ このようなアセットが作られます。

いい感じの名前を付けて編集します。

ゲージ量を扱うので、Scalar Parameter の行にある +ボタンをクリック。
ScalarParameters の中に Index [0] が追加されるので、中を開けて Parameter Name を変更します。

GaugeValue としました。
これで準備できました。
エディタ左上の保存アイコンから保存して、閉じます。
マテリアルの中でこのコレクションアセットを参照して使います。
シェーダーのノードを取り出すのと同じ要領で、CollectionParameter ノードを取り出します。


マテリアルエディタ左の Detailsパネルで、
用意したアセットをセットすると、と ParameterNameを選べるようになります。

先に作っておいた ScalarParameter の名前が出てきたら成功。
ParameterCollectionアセットは複数のマテリアルで同じ値を共有できる仕組みです。
中継役ともいえる位置づけで、マテリアルとBPが ユルく つながることになります。
アセットの依存関係にクッションとなってくれるのも魅力。

たとえば
エンジニアが先行してコレクション内にパラメータだけを用意、デザイナーに「これ使って」と申し送りしておくだけで、お互いの作業を止めることなく進めやすくなったりします。もちろん逆もありで、デザイナーがコレクションパラメータを追加してから、エンジニアに「コレコレこういう名前で作っておいたので、値の更新よろ」といった感じです。
ただ、それなりの負荷はあるので、プロジェクト内では情報共有しつつ計画的に運用するといいと思います。
今回のゲージにはパーツが全部で 6つありますが、シェーダーとしては 2つ用意します。

見た目も動きも全然タイプが違いますが、それぞれで同じ値を参照するので連動した動きが可能になります。
97. アイコンと連動するゲージ

まずはゲージから作っていきます。
ゲージ量で色が変わるのは 15. で紹介していますが、この時は 2色しか使っていませんでした。また、特定のゲージ量で色が変わるのが 32. で、これも 2段階しかありません。
今回、6段階の しきい値(閾値)で切り替えられるようにします。
基本は Stepノードと Lerpノードのコンビネーションです。
切り替えのタイミングを ScalarParameterノードで設定できるようにします。
初まりから 3段目まで

これを電車のようにつないでいきます。
最終的なカラーはあとで調整するとして、ざっくりと6色分をつなぎます。

右端の Lerpノードでゲージの増減を行っています。
マテリアルエディタの左のパネルでParameter を一覧することができます。

ゲージは 6色ですが、境界は 5か所なので しきい値用のScalarParameterは5つ。
ひとまずゲージはこれで完成。

次はアイコン。
テクスチャはこんな状態。
512 x 128px

わざとUIのテクスチャアトラスぽく配置しました。周りには他で使うパーツたちで埋まってるという想定。
アイコンひとつは 48 x 48 のサイズ。

UVは、ピクセル値をテクスチャの大きさで割ります。
アイコン一つは
48 / 512 = 0.09375
48 / 128 = 0.375
横方向は 192 / 512 で 0.375 右にずれたところからアイコンが並びます。
たとえば 左から 3つ目のアイコンを切り出す場合、
(0.09375 * 2) + 0.375 になります。
まずはアイコンを切り出す計算と、2つのアイコンを切り替える部分という構成になります。
アイコンは、初期状態(Index=0)と、任意のもの(Index= 1~5)とをスイッチします。
パラメータは 3つ。
ひとつは、ゲージと同じ ParameterCollection。
あとは、切り替わるタイミングのしきい値 Threshold と、アイコンを選択するためのIndex。
アイコンを選ぶには U座標でもいいのですが、0 1 2 3 みたいに整数っぽく扱うほうがわかりやすいので、Index と (48 / 512) を掛けたものを、アイコンの開始位置 (192 / 512) に足します。


基本は Stepノードでしきい値を越えるか越えないかで、0 と 1 が切り替わります。
それを Lerpノードがスイッチします。
これでシェーダーは完成。
さて次は、マテリアルインスタンスを作ります。
コンテンツブラウザのマテリアルアセットアイコンの上で右クリックすると、コンテキストメニューが出てくるので、一番上にある Create Material Instance を選択します。

コンテンツブラウザに並ぶと区別がつきにくい(サムネ下のラインカラーがどちらも緑で明るさが違う程度)ので名前で見分けやすくします。
ゲージ本体もマテリアルインスタンスにします。
アイコンも 5つ マテリアルインスタンスにします。全部で 6つ。

左端がゲージのマテリアルインスタンスで残りはアイコンのマテリアルインスタンスです。
できたマテリアルインスタンスをWidgetブループリントに並べます。
ここでは マテリアル本体(親マテリアルとかマスターマテリアルと呼ばれることが多いです)は配置しません。
マテリアルアセットと同じように扱えるので、コンテンツブラウザからドラッグ&ドロップしてもいいし、Imageをレイアウトしてから、マテリアルインスタンスをセットしてもOK。
まずはゲージの長さを確定させてからアイコンの位置を決めます。

ゲージの長さを100% (=1.0) として、左端の位置からのオフセットを計算してもいいですし、アナログ的で構わないならゲージを複製して手前に重ねて、Render Transform を活用するのもあり。
Pivot の X を 0.0 にすると左端が基準点になるので、Scaleの X を変えるだけ。


すべての配置が済んだら、位置調整用に複製したImageは削除するか非表示にします。
レイアウトが完了したら、マテリアルインスタンスを編集します。

左がプレビューエリアで、右のパネルにパラメータが並びます。
ゲージのマテリアルインスタンスはこんな感じ。

ここに入力したパラメータと、シェーダーとで差分があると、上書きすることになり青い ✓ チェックマークがつきます。
必要な値がセット出来たら、ゲージは編集完了です。
マテリアルインスタンスはパラメータだけを触ることになるので、ノードグラフに馴染みのないメンバーやスタッフに渡しやすいです。
続けてアイコン用のマテリアルインスタンスを編集していきます。
Index が アイコンの種類、Threshold がしきい値です。





これですべて編集完了です。
マテリアルパラメータコレクションを更新するには、
ブループリントで、 Set Scalar Parameter Value ノードを利用します。


このノードに マテリアルパラメータコレクションをセットします。
普通のBPだと、Timelineノードが使えて便利なのですが、 WidgetBPには無いので、テスト用のカスタムイベントを作って試してみます。
Float型の変数を一つ用意して、Set Timer by Eventでループさせて加算します。

一度呼び出すと動き続けます。

マテリアルパラメータコレクションと組み合わせると、違うマテリアル同士を連動させることができるのが面白いですね。
今回は以上です。
いよいよ残り3本というところまで来ました。
夏バテ気味で少々へこたれてるけど頑張る。