前回作ったミニマップ表示は Widgetの Pivot を使ったので、 今回マテリアルを使って試してみました。マテリアルだとマスクが使いやすいのでカタチを丸くしたりできま
す。でもマスクできるのはマテリアル内のテクスチャなので、マーカー等の目印やアイコンを置きにくいのが難点。Widgetのキャンバスにマスクが適用できればいいのですが・・・。
仕組みはシンプル。UVはそもそもが 0~1 なので Pivotと同じような座標で扱えます。前回作ったWidgetを複製して改造することにします。改めてリンクを貼っておきます。
今回の記事だけでも試せるように構成してみたつもりですが、細かい説明は端折っていたりするので、興味のある方は過去記事も覗いてみてください。
拡縮については、TexCoord の Tiling を変更します。ただ このTiling の扱いが、Scale と違うので少し計算が必要になります。
まずはマテリアルを新しく用意。
テクスチャを受け取る Texture Sample Prameter 2D と、Scalar Param が3つ。
それぞれUV範囲の大きさと位置を受け取ります。正方形を想定してるので、サイズに関してのパラメータは一つです。
まん丸のマップにしたいので、キャンバスパネルを正方形にします。
中の Image には 新しく用意したマテリアルをセットします。
今回マテリアルで拡縮するので サイズは固定です。
変数は以下を用意しました。上の4つはVector2D型です。
あとからここにもう一つ加えます。
setMapTexture
テクスチャを受け取る関数を改造します。
マテリアルを扱うので、Get Dynamic Materialノードで、マテリアル インスタンス ダイナミックを作って、変数化しています。計算用の値をここで準備しています。
キャンバスのサイズは、一旦キャストしないと参照できません。
最終的に決め打ちで固定の値をセットしてやればいいと思いますが、開発中はレイアウト調整で細かく変更したくなると思うので、ブループリントのことを気にせず触るようにするためのテクニックです。
updateTranslation
次はマップを任意の位置に移動させる関数。
XY,座標を受け取って、テクスチャのUVに変換しています。実際はもっと補正が必要だと思います。今回は左上が (0, 0) の座標空間で、マップの中心が テクスチャサイズの 1/2 を前提としてます。マップテクスチャの1ピクセルがワールド空間のどれくらいかによって補正を掛けることになるので、テクスチャのサイズ選びはビジュアルも含めて、UI設計が難しいお仕事の中でも上位レベルになります。
前回のはマウスで操作するので、用途としてはインベントリ画面とかポーズメニュー画面なんかでマップ確認というイメージを想定していました。
Pivot の計算は不要なので、関数 updatePivot は不要になりました。
替わりに、新しくマクロを作ります。マウスドラッグに追随する際の表示倍率に合わせた移動値を計算します。
このマクロは、ポジションを変更するイベントで使います。
ここからはマウスイベント用の関数を見ていきます。
OnMouseButtonDown
これはそのまま変更なしです。
OnMouseButtonUp
これもそのまま。
OnMouseMove
ここに、新しく作ったマクロを仕込みます。Pivotの更新する関数は外しました。
マクロにしなくてもいい気がしますが、コンパクトになるので。
OnMouseWheel
ホイールを転がしてスケールを変更する際の符号が逆になります。
テクスチャを切り出すときのサイズは、Tiling で指定します。表示サイズが変わらないので、値が小さいほど切り出す範囲が小さくなって、結果的に拡大することになります。
例えば 1024x1024のテクスチャがあったとします。表示サイズはちょうどその 1/2の 512x512だった場合、下図のようなイメージになります。
表示倍率が上がるほど、Tilingの値は小さくなっていきます。虫眼鏡で拡大するのと同じ要領ですね。
最後の関数
OnMouseLeave
EventGraphにおかれるやつ。
最後にあったPivot更新の関数は不要になりました。
これで、関数&イベントの改造は終了です。
仕上げに、 EventConstruct にあった Pivotの更新を、マテリアルへの更新に変えます。
マップの表示の縦横比が 1:1 の正方形用なので、Vector2D の持つ値を一つだけ使います。
これでWidgetは完成。
テスト用のレベルブループリントも少しだけ変更になります。
今回作ったWidget用だけにまとめるとこんな感じです。
テストしてみましょう。
うまく動いているようです。
丸い形をしているので、回転させることができます。
この形だとたいていはHUDに置かれるので、マウスで操作できなくてもよいですね。
ということでもう少し遊んでみます。
レベルブループリントに変数を一つ追加。スタート位置 兼 補正値です。
関数の前でセットしてそのまま関数に渡してます。
あとは、EventTick でカメラ位置と回転値を拾って、Widgetに渡します。
マップには、 Plane のメッシュを中央に置いて、XY方向に それぞれ100倍して、マップのテクスチャを貼りつけます。
もともと置いてあった Floor はこんなサイズ。
Plane を 100倍すると、端っこのポジションは ±5000 になります。1辺の長さが 10000 になるので、テクスチャサイズ 2048 を割ると、 0.2048 になります。取得したカメラポジションに対して掛けてから、Widgetに渡します。
あと、マップのWidgetには 中央に ▲ を置いておきます。
プレイしてみると・・・。
静止画ですが、いい感じにグリグリと連動して動いてます。
マップ部分だけGIF化しました。
FPSカメラなので、床から離れているのもあって見た目とマップ位置のギャップを感じますが、いろいろ補正を試してみると何か発見があるかもしれません。
TPSだと、キャラの向きとカメラの向きを反映させるために、カメラのFOVに合わせた扇形の図形を重ねたりします。
なんとか形になったので、今回はこの辺で。
ではでは
ステキなミニマップライフを!