読者です 読者をやめる 読者になる 読者になる

みつまめ杏仁

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

Widgetでじゃらじゃらじゃら~ばん

UE4 UMG Widget UI

f:id:hiyokosabrey:20160131232631p:plain

スコアとかの数字がもったいぶって確定するアレです。

ドラムロールなんかがSEだったりするとドキドキしたりするアレです。

くるくる回ったりしないので、作るのは簡単です。

いままでの作りとそれほど変わらないので、新しいテクニックはほぼ出てこないと思いますが、ネタ的に作っておこうかなという・・・

 

で、テクスチャを用意します。

UVの範囲が分かるように色分けしたレイヤーを置いてます。

f:id:hiyokosabrey:20160131233451p:plain

512x256のテクスチャで、1文字 96x80 です。

キャンバスパネルの Imageパーツにセットするのですが、テクスチャの一部を切り出すのでマテリアルが必要になります。

f:id:hiyokosabrey:20160131234517p:plain

TextureCoordinate ノードを ComponentMaskを使って UとVを別居させます。

分けたU値とV値それぞれに、スケール(Tiling)を掛け、オフセット(Offset)を

足し算するようにScalarParameterValueノードを4個つなぎます。

スケール(Tiling)は初期値を 1.0、オフセット(Offset)は0.0 にしておきます。AppendVectorノードで再び UとVは一つのベクターによりを戻して同居させたら、テクスチャにつないで完了です。これは親のマテリアルとして利用します。

 

数字はすべて同じ大きさでなので、マテリアルインタンスを使います。

コンテンツブラウザに親マテリアルができているのを確認したら、右クリックしてインスタンスを作ります。> Create Material Instance

f:id:hiyokosabrey:20160201222622p:plain

 インスタンスができたら、編集してパラメータをセットします。

f:id:hiyokosabrey:20160201223304p:plain

数字ひとつの大きさが 96x80なので、テクスチャサイズで割ると、UV空間でのサイズが判ります。UV空間はテクスチャサイズに関係なく 0.0~1.0 の範囲です。

f:id:hiyokosabrey:20160201224230p:plain

判明したサイズは、マテリアルのTextureCoordinateノードの Tiling に渡します。

UとV個別にパラメータを掛け算するようにしているので、下のような状態にします。

f:id:hiyokosabrey:20160201223315p:plain

 オフセットは、Widgetブループリントの方でいじるので、0.0とかで問題ないです。

インスタンスは編集完了なので保存して閉じます。

次におまけのテキスト「Points」もインスタンスで用意します。

f:id:hiyokosabrey:20160201225933p:plain

上から 160px の位置にあるので、160÷256 = 0.625 をOffsetVに渡します。

サイズはそれぞれ計算して Tiling の値としてセットします。

f:id:hiyokosabrey:20160201225452p:plain

編集完了です。保存して閉じます。

 

マテリアルの準備が終わったので、次は

数字を担当する子Widgetを用意します。

編集モードをDesigner にして、キャンバスにImageパーツをレイアウトします。

サイズは、98x80にします。IsVariableのチェックが付いていなければ付けます。

Detailsタブの Appearance > Brush にマテリアルインスタンスをセットします。(コンテンツブラウザでフォーカスしておいてから白い←矢印をクリック)

f:id:hiyokosabrey:20160201232249p:plain

 

 編集モードを Graphに切り替えます。

変数を3つ用意します。

Number ・・・ 整数型: 最終的に表示する数字を保持する

TexOffsetArray ・・・ Vector2D型(配列): 数字のUVオフセット値

ActiveFlag ・・・ Boolean型: シャッフルするかしないか

 

さっそくEventConstructノードにつないで初期値をセットします。

f:id:hiyokosabrey:20160201232945p:plain

Vector2D型の配列は、0~9の各数字のUV値です。マテリアルのパラメータに渡します。

 

次に、親から数字を受け取るための関数を用意します。

f:id:hiyokosabrey:20160201233427p:plain

 次に数字を切り替えるための関数を用意します。

f:id:hiyokosabrey:20160201233602p:plain

整数型の引数を一つ受け取れるようにします。それをつかって、数字のUV値を取り出し(GETノード)マテリアルパラメータに渡します。

 キャンバスに置いたImageパーツ(上図の Image_40ノード)に割り当ててあるマテリアルから、GetDynamicMaterial ノードをつなぐことによって、SetScalarParameterValueノードがつながるようになります。便利! 通常のブループリントだと、CreateDynamicMaterialInstanceノードを使います。

 

次にこの関数を使って、シャッフルを止める関数を作ります。

f:id:hiyokosabrey:20160201234412p:plain

シャッフルを制御するブーリアン型の変数をFalseにします。

 

仕上げに、シャッフルのしくみをEventTickにつなぎます。

f:id:hiyokosabrey:20160201234718p:plain

RandomIntegerノードは、0から 指定した値までの乱数を発生させます。

EventTickノードは常時処理が走って(FlashのENTER_FRAMEみたいな)て、必要がなくなると処理が流れないようにしないと、無駄に動き続けてしまいます。

そこで、フラグとしての変数を使います。

 

これで、子Widgetの編集は完了です。コンパイルして保存しますが、親Widgetの編集をスムーズ進めるために、いったん閉じておくことをおすすめします。

 

 

Widgetを作ります。

編集モードをDesignerにしたら、

左のPaletteタブから UserCreated というカテゴリの中をチェック。

作った子Widget がいるはずなので、見つけてキャンバスにドロップします。

f:id:hiyokosabrey:20160202000008p:plain

「Points」もここでImageパーツを新しく追加して配置します。

 

 配置できたら、編集モードをGraphに切り替えて、変数を2つ用意します。

Numbers ・・・ 整数型: Levelから受け取る。

NumArray ・・・ 各桁の数字パーツをコントロールするための配列

 

配置したばかりのImageパーツを配列に積みます。 この配列(Num Array)の Variable Type Widgetの型 にします。

f:id:hiyokosabrey:20160202233947p:plain

 

次に数字をバラバラにして、子Widgetたちに渡す関数を用意します。

f:id:hiyokosabrey:20160202235653p:plain

変数ノード TempDigit は、この関数内のみ有効なローカル変数です。

Foreachループで回るたびに10を掛けて、数字の桁をばらすために利用します。

Branchノードは、子Widgetが配列に積まれていない状況が発生した場合に備えています。

最後に、シャッフルを止める関数です。

f:id:hiyokosabrey:20160203001556p:plain

 右端のノードは、子Widgetの中の関数です。

Widgetはこれで編集終了です。コンパイルして保存します。

 

ようやくレベルブループリントまできました。

Viewportに配置して表示したい数字をセット。下の図では0~99999のランダム値を生成させるノードをつないでいます。

Inputノードでシャッフルを止める関数を呼ぶようにすれば出来上がりです。

f:id:hiyokosabrey:20160203002152p:plain

 

 

f:id:hiyokosabrey:20160203003256g:plain

 完成