みつまめ杏仁

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

ついでに丸い形のミニマップ表示を作ってみる

 前回作ったミニマップ表示は Widgetの Pivot を使ったので、 今回マテリアルを使って試してみました。マテリアルだとマスクが使いやすいのでカタチを丸くしたりできま
す。でもマスクできるのはマテリアル内のテクスチャなので、マーカー等の目印やアイコンを置きにくいのが難点。Widgetのキャンバスにマスクが適用できればいいのですが・・・。

 

f:id:hiyokosabrey:20190120160103p:plain

 仕組みはシンプル。UVはそもそもが 0~1 なので Pivotと同じような座標で扱えます。前回作ったWidgetを複製して改造することにします。改めてリンクを貼っておきます。

 

limesode.hatenablog.com

 今回の記事だけでも試せるように構成してみたつもりですが、細かい説明は端折っていたりするので、興味のある方は過去記事も覗いてみてください。

 

 

 拡縮については、TexCoord の Tiling を変更します。ただ このTiling の扱いが、Scale と違うので少し計算が必要になります。

 

まずはマテリアルを新しく用意。

f:id:hiyokosabrey:20190118002438p:plain

 テクスチャを受け取る Texture Sample Prameter 2D と、Scalar Param が3つ。

それぞれUV範囲の大きさと位置を受け取ります。正方形を想定してるので、サイズに関してのパラメータは一つです。

 

 

 

まん丸のマップにしたいので、キャンバスパネルを正方形にします。

f:id:hiyokosabrey:20190119212425p:plain

中の Image には 新しく用意したマテリアルをセットします。

今回マテリアルで拡縮するので サイズは固定です。

 

変数は以下を用意しました。上の4つはVector2D型です。

f:id:hiyokosabrey:20190119213104p:plain

あとからここにもう一つ加えます。

 

 

setMapTexture

テクスチャを受け取る関数を改造します。

f:id:hiyokosabrey:20190120113803p:plain

  マテリアルを扱うので、Get Dynamic Materialノードで、マテリアル インスタンス ダイナミックを作って、変数化しています。計算用の値をここで準備しています。

 

 キャンバスのサイズは、一旦キャストしないと参照できません。

f:id:hiyokosabrey:20190119224255p:plain

 最終的に決め打ちで固定の値をセットしてやればいいと思いますが、開発中はレイアウト調整で細かく変更したくなると思うので、ブループリントのことを気にせず触るようにするためのテクニックです。

 

 

updateTranslation

 次はマップを任意の位置に移動させる関数。

f:id:hiyokosabrey:20190119224837p:plain

 XY,座標を受け取って、テクスチャのUVに変換しています。実際はもっと補正が必要だと思います。今回は左上が (0, 0) の座標空間で、マップの中心が テクスチャサイズの 1/2 を前提としてます。マップテクスチャの1ピクセルがワールド空間のどれくらいかによって補正を掛けることになるので、テクスチャのサイズ選びはビジュアルも含めて、UI設計が難しいお仕事の中でも上位レベルになります。

 前回のはマウスで操作するので、用途としてはインベントリ画面とかポーズメニュー画面なんかでマップ確認というイメージを想定していました。

 

 

 Pivot の計算は不要なので、関数 updatePivot は不要になりました。

 替わりに、新しくマクロを作ります。マウスドラッグに追随する際の表示倍率に合わせた移動値を計算します。

f:id:hiyokosabrey:20190120005446p:plain

 このマクロは、ポジションを変更するイベントで使います。

 

 

 

ここからはマウスイベント用の関数を見ていきます。

 

OnMouseButtonDown

これはそのまま変更なしです。

f:id:hiyokosabrey:20190112095622p:plain

 

 

OnMouseButtonUp

これもそのまま。

f:id:hiyokosabrey:20190112102524p:plain

 

 

OnMouseMove

ここに、新しく作ったマクロを仕込みます。Pivotの更新する関数は外しました。

f:id:hiyokosabrey:20190120010529p:plain

マクロにしなくてもいい気がしますが、コンパクトになるので。

 

 

OnMouseWheel

ホイールを転がしてスケールを変更する際の符号が逆になります。

f:id:hiyokosabrey:20190120011007p:plain

  テクスチャを切り出すときのサイズは、Tiling で指定します。表示サイズが変わらないので、値が小さいほど切り出す範囲が小さくなって、結果的に拡大することになります。

 例えば 1024x1024のテクスチャがあったとします。表示サイズはちょうどその 1/2の 512x512だった場合、下図のようなイメージになります。

 

f:id:hiyokosabrey:20190120020021p:plain

表示倍率が上がるほど、Tilingの値は小さくなっていきます。虫眼鏡で拡大するのと同じ要領ですね。

 

 

 最後の関数

OnMouseLeave

EventGraphにおかれるやつ。

最後にあったPivot更新の関数は不要になりました。

f:id:hiyokosabrey:20190120111819p:plain

 

 

これで、関数&イベントの改造は終了です。

 

仕上げに、 EventConstruct にあった Pivotの更新を、マテリアルへの更新に変えます。

f:id:hiyokosabrey:20190120112534p:plain

マップの表示の縦横比が 1:1 の正方形用なので、Vector2D の持つ値を一つだけ使います。

これでWidgetは完成。

 

 

テスト用のレベルブループリントも少しだけ変更になります。

今回作ったWidget用だけにまとめるとこんな感じです。

f:id:hiyokosabrey:20190120115442p:plain

テストしてみましょう。

f:id:hiyokosabrey:20190120120124g:plain

うまく動いているようです。

 

丸い形をしているので、回転させることができます。

この形だとたいていはHUDに置かれるので、マウスで操作できなくてもよいですね。

 

 

ということでもう少し遊んでみます。

レベルブループリントに変数を一つ追加。スタート位置 兼 補正値です。

関数の前でセットしてそのまま関数に渡してます。

f:id:hiyokosabrey:20190120142806p:plain

 

あとは、EventTick でカメラ位置と回転値を拾って、Widgetに渡します。

f:id:hiyokosabrey:20190120142943p:plain

 

マップには、 Plane のメッシュを中央に置いて、XY方向に それぞれ100倍して、マップのテクスチャを貼りつけます。

f:id:hiyokosabrey:20190120153807p:plain

f:id:hiyokosabrey:20190120143324p:plain

もともと置いてあった Floor はこんなサイズ。

f:id:hiyokosabrey:20190120144147p:plain

Plane を 100倍すると、端っこのポジションは ±5000 になります。1辺の長さが 10000 になるので、テクスチャサイズ 2048 を割ると、 0.2048 になります。取得したカメラポジションに対して掛けてから、Widgetに渡します。

f:id:hiyokosabrey:20190120144507p:plain

 

あと、マップのWidgetには 中央に ▲ を置いておきます。

 

プレイしてみると・・・。

f:id:hiyokosabrey:20190120145142j:plain

f:id:hiyokosabrey:20190120145203j:plain

 静止画ですが、いい感じにグリグリと連動して動いてます。

マップ部分だけGIF化しました。

f:id:hiyokosabrey:20190120151600g:plain

 FPSカメラなので、床から離れているのもあって見た目とマップ位置のギャップを感じますが、いろいろ補正を試してみると何か発見があるかもしれません。

 

 TPSだと、キャラの向きとカメラの向きを反映させるために、カメラのFOVに合わせた扇形の図形を重ねたりします。

 

なんとか形になったので、今回はこの辺で。

 

ではでは

ステキなミニマップライフを!