みつまめ杏仁

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

UE4で 「7セグ」表現を作ってみる

f:id:hiyokosabrey:20160206034943p:plain

いかにもデジタルな見た目の数字といえば、7セグです。

 Amazonで気になる商品名を見つけたので貼ってみます。

 これを再現してみようと思います。

 普通に0~9の点灯パターンを作ったのでは面白くないので、デジタルらしい作りにチャレンジです。

まずはテクスチャ。

f:id:hiyokosabrey:20160204225002p:plain

↑実寸で64x256 モノクロです。これだけです。

ほんとうは左右非対称だったりしますが、少ない容量で大きな表示を目指したいのでこれでいきます。

このテクスチャはマスクとして利用します。テクスチャの設定は以下。UI表示を想定してるのでミップマップは無しで。

f:id:hiyokosabrey:20160204225754p:plain

インポートしたテクスチャをもとにマテリアルを作ります。

f:id:hiyokosabrey:20160204230157p:plain

マテリアルの基本設定は以下。

f:id:hiyokosabrey:20160204230315p:plain

暗い赤と明るい赤、これをLeap(LinearInterporate)ノードのAlpha値のPINにつないだScalarParameterValueノード(パラメータ名:Switch)の値によって点灯/消灯状態の切り替えを行います。1.0で点灯、0.0で消灯になります。

 

マテリアルができたらWidgetを用意します。

編集モードをDesignerにしてImageパーツをドラッグ&ドロップします。

ドロップしたら、サイズをテクスチャと同じ 64x256にします。

Appearance > Brush > Image のところで、作っておいたマテリアルをセットします。

f:id:hiyokosabrey:20160204231749p:plain

サイズはそのままテクスチャサイズでいきます。

Appearance > Brush > Image のところに作ったマテリアルをセットします。

 次にヨコ棒。これが少し厄介。

レイアウトするとき白い●が8個あります。バウンディングボックスのアンカー的な存在だと思いますが、キャンバススロットは回転できないつくりのようで、90度回すには、Detailsタブの下の方、Render Transform の中にある Angle で回します。すると下のようになります。

f:id:hiyokosabrey:20160205224101p:plain

 バウンディングボックスとは連動していないので、移動させてバウンディングボックスがキャンバスの外に出たりすると不思議なことが起こります。バウンディングボックス基準ではみ出た部分がクリッピングされるのです。(理屈はわかるけど・・・)

そこで、緑の枠線に沿うように調整します。

f:id:hiyokosabrey:20160205225348p:plain

 タテ棒とヨコ棒ができたのであとはコピペで並べていきます。

f:id:hiyokosabrey:20160205230102p:plain

並べ終えたら、パーツを配列に入れます。

編集モードをGraphに切り替えてImage型の配列変数を用意します。

上図の番号順になるようにつなぎます。

f:id:hiyokosabrey:20160206012414p:plain

f:id:hiyokosabrey:20160205231259p:plain

 

ロータリーエンコーダというものがあります。それをスタティックメッシュで作った場合はUVの当て方で簡単に実現できます。今回はUMGでバラバラのパーツで組み上げているので、ビット演算を使うことにします。

まずは点灯している状態を1、消灯している状態を0とします。

f:id:hiyokosabrey:20160206015921p:plain

0~6の場所にあるパーツが特定のパターンで点いたり消えたりすることで数字を表現します。0と1で表現できるので、2進数で考えることにします。

進数変換ができる電卓(Windowsにバンドルされてるやつで十分)を用意すると便利です。

f:id:hiyokosabrey:20160206020204p:plain

この方法で他の数字も割り出します。

f:id:hiyokosabrey:20160206023004p:plain

電卓に進数変換が無い場合は、8個の並んだマスに固定の数字が振られているとして計算します。

f:id:hiyokosabrey:20160206024102p:plain

ではそろそろ関数を作ります。

関数にはローカル変数という、関数内のみ有効という一時的な変数を作ることができます。

頑張って計算した0~9の数値をローカルの配列変数に格納します。

名前はテキトーです。

f:id:hiyokosabrey:20160206024748p:plain

あともう一つビット演算用に Temp というローカル変数を用意します。

初期値は 1 を入れておきます。

 

数値を受け取って処理するので、Inputs(引数)をひとつ整数型で追加します。

で、できたのがコレ。

f:id:hiyokosabrey:20160206025402p:plain

あとはこの関数を呼び出す際に、0~9の値を渡せばOK。

Widgetの編集は終了です

 

仕上げにこのWidgetをレベルから表示してみます。

f:id:hiyokosabrey:20160206034221p:plain

完成です。

 

 

 

ここからは解説になります。

 ビット演算の部分はこのノード Bitwise AND ってやつを使います。

f:id:hiyokosabrey:20160206025819p:plain

これは単純に掛け算をするのですが、ビット同士での掛け算になります。

f:id:hiyokosabrey:20160206030918p:plain

0と1の掛け算になるので、当然 0を掛けたところは必ず0になります。1を掛けたところは 相手によっては1か0のどちらかになります。

上の例では結果的に5番目が1になりました。では次のケース。

f:id:hiyokosabrey:20160206031459p:plain

これらは何をしているかというと、調べたい場所を1、それ以外を0にして掛け算

することで、そこに1があるか? という調査ができるのです。

この方法はビットマスクともいいます。

右から順番に調べていって、結果が全部 0になった場合はもちろん0ですが、1が入っていたら、0 以上の値になります。そこを利用します。

 

パーツの数は7個。例えば 5 という数字にしようとしたら、

f:id:hiyokosabrey:20160206033550p:plain

f:id:hiyokosabrey:20160206033736p:plain

こんな感じ。