みつまめ杏仁

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

[3D]シンプルなリストメニュー作ってみる

前回のタブっぽい何かに、リストメニューっぽい何かを追加してみます。

f:id:hiyokosabrey:20180505224715j:plain

背景のマテリアルにPARAGONのアセット使わせていただきました。

 

その前に前回のマテリアルで、大事な設定を見つけました。

UI 表示では フォグの影響を受ける必要はないので、Apply Fogging のチェックを外してみました。

f:id:hiyokosabrey:20180505112157p:plain

すると、Intructions(命令)の数が減ったのです!

f:id:hiyokosabrey:20180505112803p:plain

f:id:hiyokosabrey:20180505112814p:plain

頂点シェーダの処理が約1/2、TextureSamplersの数も1/4になったので、これは効果アリですね。次回から確実に外していこう。

 

では、リストメニュー用のスタティックメッシュを用意します。

Blenderで↓のようなメッシュを作りました。

f:id:hiyokosabrey:20180505113546p:plain

下にある黒っぽいのはドロップシャドウ用のメッシュです。2面のポリゴンで1つのオブジェクトになっていて、こうことができるのがスプライトにない強みですね。作るときは1枚だけ作って複製し、ずらして統合します。影のカラーを付けたいので頂点カラーを付けています。

 

ちなみに作業用のテクスチャは以下。等間隔に並べます。

f:id:hiyokosabrey:20180505123600p:plain

この色分けはUV範囲を分かりやすくするためにレイヤーで色を載せています。この色分けに沿ってUVの頂点をきっちり当てます。

f:id:hiyokosabrey:20180505123854p:plain

エンジンにインポートする際は、グレースケールにして、TGA形式にします。

f:id:hiyokosabrey:20180505123615p:plain

 

メッシュはFBXでエクスポートします。流れは前回の記事と同じですが、頂点カラーを有効にする必要があります。まずは Import Settings でやる場合は、以下の場所にあります。

f:id:hiyokosabrey:20180505124833p:plain

 

インポートした後に有効にすることもできます。その場合は StaticMeshエディターの右のDetailsタブの中にあります。

f:id:hiyokosabrey:20180505125110p:plain

変更したら、Assetメニューから Remport(再読み込み)すれば反映されます。

f:id:hiyokosabrey:20180505125321p:plain

 

テクスチャインポートしたら、マテリアルを作成します。

f:id:hiyokosabrey:20180505132010p:plain

 

頂点カラーを使うには 専用のノードが用意されています。そのまま Emissive Color に渡してもいいのですが、ブループリントから色味をいじりたいので、MultiplyノードでVectorParameterノードを掛けています。

f:id:hiyokosabrey:20180505130420p:plain

 

リストの文字は、UVの位置をずらしてバリエーションを出します。

f:id:hiyokosabrey:20180505132057p:plain

今回移動するのは縦方向、Vの値だけが変化すればいいので、Uの値はそのままにします。

ちなみに Append は合成、Add は加算です。

A と B を Append すると、 (A, B) になって

A と B を Add すると、 A + B になります。

 

白いラインが全部一緒なので、慣れないと分かりにくいのですが、上の場合、

TexCoordから出てるのが、(U, V) の Flort2 または Vector2 とよばれる型。

左端の2つのノードは 単品のFloat型で、これを Append でくっつけて、

(0, OffsetV) にして、Add ノードで、(U, V) に加算しています。なので、

(0, 0.5) + (0, 0.25) だと (0, 0.75) になるのです。この単品の float が何本になってるかをノードの前後で把握することのが、マテリアル攻略の助けになります。

ちなみに下の例では、エラーにはなりませんが・・・

f:id:hiyokosabrey:20180505132710p:plain

(0, 0) に対して 単品の float を足すので、OffsetV = 0.25 だとしたら、

(0.25, 0.25) になります。これではUVが斜めに移動することになります。

 

マテリアルができたので、次にマテリアルインスタンスを作ります。

 マテリアルのアセットアイコンの上で右クリックしてコンテキストメニューから選択します。一番上にあります。

f:id:hiyokosabrey:20180505225010p:plain

マテリアルインスタンスにすると、仕込んでおいたパラメータのみ触ることができるようになります。(チェックボックスにチェックを付ける必要があります)

f:id:hiyokosabrey:20180505225433p:plain

文字を変更するのはUV値のVの方なので、パラメータ ”OffsetV” の値を変更します。

今回は48px ÷ 512px = 0.09375 が間隔なので、パラメータは以下のようになります。

f:id:hiyokosabrey:20180505230933p:plain

 

テクスチャに並べておいたテキスト分のマテリアルインスタンスを用意します。

いまのところコンテンツブラウザは以下のような状態。

f:id:hiyokosabrey:20180505231243p:plain

 等間隔に並んでいるので計算させた方がよさそうに見えますが、ゲーム開発においてメニュー項目なんてのは変更されるのが常です。さらにイベント用ROMなど特殊な状況のパッケージを作る際にも意図的に変更することがあります。このようなアセット構造にしておくことで、プログラマーとデザイナーとで分業しやすい状態にできるのでオススメです。

 

ブループリントアクターを用意します。

f:id:hiyokosabrey:20180506170156p:plain

StaticMesh とChildActor をAdd Componentボタンから追加します。

f:id:hiyokosabrey:20180506031559p:plain

追加しただけだと空っぽなので、Static Meshには さきほどインポートしたMeshアセットと対になるマテリアルインスタンスをセットします。

f:id:hiyokosabrey:20180506102851p:plain

 

最後の Child Actorコンポーネント には、前回の記事で作ったブループリントをセットします。

f:id:hiyokosabrey:20180506103551p:plain

 

Child Actorコンポーネントは、そのままだと中身にアクセスできないのでConstruction Script 内でキャストして変数化しておきます。

f:id:hiyokosabrey:20180506102633p:plain

(なんかちょっと不思議な感じ、間違ってるのかな・・・)

続きを組む前に、関数を2つ用意。

 

 見た目をデフォルトにする関数と、

f:id:hiyokosabrey:20180506111409p:plain

f:id:hiyokosabrey:20180506111154p:plain

 

見た目をフォーカス状態にする関数。

f:id:hiyokosabrey:20180506111421p:plain

f:id:hiyokosabrey:20180506111204p:plain

 

ConstructionScript 内で表示位置と状態のセッティングは済ませておきたいので、

StaticMeshComponentを配列変数にして、そこから ForEachLoop でいろいろセット。

f:id:hiyokosabrey:20180506114230p:plain

ループ処理の前後どちらでも問題ないと思うけど(上図では後)、配列に仕込んだ数を変数に持たせておきます。

 

準備ができてきたので、前回作ったタブっぽいウィンドウのブループリントを再び編集します。

f:id:hiyokosabrey:20180506170306p:plain

イベントディスパッチャーを追加します。

f:id:hiyokosabrey:20180506164617p:plain

作ったイベントディスパッチャーは、アニメーションの終了を通知するためのもので、TimeLineノードのCompleteピンにつなぎます。

f:id:hiyokosabrey:20180506164853p:plain

 これでこのブループリントは編集終了。

 

次はこのイベントディスパッチャーをバインドしてやります。

 

再び今回のBP。

f:id:hiyokosabrey:20180506170128p:plain

 

f:id:hiyokosabrey:20180506171016p:plain

 これで、ウィンドウの出現アニメーションが終わるのを待つことができます。

出現が完了したら、カスタムイベントで受け取って、リストメニューを表示する、という流れです。ここでリストのフォーカス位置を管理するための変数 int型 をひとつ用意しています。上図の FocusIndex。

 

右下の部分は、このあと何度か登場するので、関数にしてしまいます。

f:id:hiyokosabrey:20180506190940p:plain

まとめて選択しておいて、右クリック > Collapse to Function を選びます。

できた関数ノードを編集して、Pure型にしてみます。

f:id:hiyokosabrey:20180506191422p:plain

ノードが変化します。

f:id:hiyokosabrey:20180506191616p:plain

 今フォーカスされてるやつをGetするだけの関数だけど、こうしておくことで、ノードもスッキリして、名前で何をしてくれるかわかるし、関数の中にチェックの仕組みも入れやすくなります。

例えば下の例は StaticMeshComponentの配列から正しく取り出せるかチェックする場合。

f:id:hiyokosabrey:20180506211702p:plain

 

で、リストのフォーカスをくるくると切り替える仕組みをカスタムイベントで組みます。

f:id:hiyokosabrey:20180506231026p:plain

 このイベントの Inputs(引数)は int型で、+1-1 を受け取ります。

 

 ブループリントはこれで一応完成です。

 

さっそくレベルブループリントからテストしてみます。

f:id:hiyokosabrey:20180506213255p:plain

左の Set View Target with Blend ノードは、任意のカメラに切り替えるときに使います。Spawn Actor from Class ノードを使ってActorブループリントをシーンに呼び出します。

f:id:hiyokosabrey:20180506213641p:plain

キー入力でテストしてみたので、Inputノードは カーソルキーの ↑(Up)↓(Down)です。

再生してみると、

 

f:id:hiyokosabrey:20180506225458g:plain

GIFが重くて上げられなかったので2つに分けました。

f:id:hiyokosabrey:20180506225543g:plain

 

 うまく動いてくれました。

PostProcess の影響を受けるので、カラーのコントロールが難しいですが、UMGと大して変わらない印象です。UVアニメーションで凝ったことができるのと、アルファの透明部分をカットして描画負荷を軽くしたり、UVがレクト(長方形)じゃなくてもいので、テクスチャを節約できたり、頂点カラーが使えたりと、メッシュでUIパーツを作成できると、いろんな表現ができるのでとても楽しいです。

個人的に、お手軽さではUMGの方に軍配が上がりますけどね。

 

ではでは今回はこの辺で

ステキな[3D]UIライフを!