ふと気がつくと最後の更新から1ケ月が過ぎようとしててびっくりです。近所ではセミが鳴き始めました。ノートPCのファンに問題があるようでUE4を起動すると3秒と触れないくらい熱くなるため、ミニUSBファン(コンセント接続)と扇風機で冷やすのですが、マウスを握る腕の方が冷えすぎて辛い今日この頃です。
さてさて、今回はシーズン5も大好評の Fortnite からネタをもらうことにしました。
画面上部の方向計をUMGで作ってみます。UE4で作ってるのでUMGに違いない。はず。
スクショを取って解析しました。1920x1080で取って、Photoshopでフォントと目盛りを合わせてみて、まずは N ~ S まで(360度分)を横幅2048pxの画像に並べてみた。
コンパスは方向を指すので、ぐるぐるとループするようにWrap(ラップ:テクスチャが繰り返される)するはず。
残りの空白をみてピンときました。ループするので、重複部分が入りそう。
そこは画面の表示サイズをみて確信しました。表示幅もだいたい 512pxの様子。
端がアルファで消えてるので確定はできませんけどね。
目盛りも360度分 でちょうど 1536px、 ということは 75% で残りの 25% は 512px と実にキリがいい。
そこでテクスチャサイズを、横 2048px、表示幅512px じゃないかと想定。
で、できたのがこれ。2048x32px
左端から512pxの幅を表示した際に 0度(北)が真ん中に来るようにしています。
Nが左端から256pxの位置です。
ちなみにフォントは Yu Gothic UI (游ゴシック)にしたらピッタリな感じです。
あと、両端がフェードして消えているので、マスクテクスチャも用意します。
これをUE4にインポートします。
UE4のプロジェクトはサードパーソンのテンプレで進めます。
2のべき乗でテクスチャ作ると自動でMipMap作られる設定になっているので、必ず、NoMipmapsにします。
マテリアルはシンプルです。横方向にスクロールするだけです。
マスクテクスチャは、グレースケールで作っているので、Rチャンネルのピンから取り出して数字テクスチャのアルファチャンネルと乗算しています。
表示する大きさは横が512pxなので、TexCoord ノードの中の設定を変更します。
このマテリアルを、UMGのImageパーツにセットします。
ここまでは順調でしたが、ふと、どんな値を受け取るのか気になったので、チェック用のTextBlockを置くことにします。上部の◆は画面中央を示す目印。
編集モードをグラフに移して、カスタムイベントを用意します。
受け取ったRotateをBreake Rotator で各軸毎にバラして、Z軸の回転値を表示するように チェック用のTextBlockに対して Set Text します。
Widgetの準備はできました。
つぎにThirdPersonCharacterのブループリントを開きます。
マネキン君を選択した状態で、
ワールドアウトライナからハイライトされてるやつをチェック。
右端の Edit ~ をクリック。
方向を変更している関連のイベントを探します。
キー入力を受けてカメラを回しているので、それっぽいやつ・・・
Movement inputのコメントを発見。Get Controll Rotaton ノード、そこからZ軸の値だけを取り出してる。
よし、この値を確認してみようということで、PrintStringノードでチェックするとどうやら当たりのようです。
Widgetにこの値を流せばいけそうです。
HUDクラスのブループリント
ActorクラスのブループリントからHUD表示のWidgetに値を渡す場合、今回はHUDクラスのブループリントを作って対応します。
HUDクラスのブループリントを作ったら、
Content > ThirdPersonBP > Blueprints の中にある
ThirdPersonGameMode を編集してセットします。
これでHUDクラスBPにアクセスが可能になります。
作ったHUDクラスBPを編集して、Widgetを表示するようにします。
さらにカスタムイベントを用意して、マネキン君からの呼び出しに応えます。
HUDクラスBPの編集は以上です。
マネキン君のBPに戻ります。
ここで、HUDクラスBPを経由してコンパスのWidgetに値を送ります。
まず Event BeginPlayを取り出して、HUDクラスBPを変数化しておきます。キャストノードからPromote to Variable すると簡単です。
あとは、Movement input 処理の最後にHUDクラスBPに用意したカスタムイベントをつないで値を渡します。
ここで確認してみます。
マウスでカメラを回すと、0~360の範囲で値が変化しています。影の向きがひねくれていなければ南中で180°です。
方位 - Wikipedia で調べたら、360°式というやつですね。
これをテクスチャのUVオフセット値にしてやればよさそうです。
受け取った値を 360で割ると 0.0 ~1.0 の値にできます。
UVの移動範囲は 0.0 ~ 0.75 なので、 Lerp ノードで線形補間します。
これで確認します。
うまくいってます。完成です。
テクスチャのUVスクロールで表現してみましたがいかがでしょうか。
実際には 特定の対象の方角を示すマーカーも一緒に動いていることがあるので、テクスチャを使わない方法かもしれません。
HUDクラスのブループリントを使うあたりはちょっと面倒かもしれないですが、GameModeがセットされていればレベル遷移しても安定してアクセスできるし、HUD周りの管理も集約できるので良いと思うのですが、他にもっといい方法やオススメなどありましたら、コメントやTwitterで教えていただけると嬉しいです。
アクションゲームのHUDなので、なるべく負荷がかからないつくりにする必要があります。GPUの描画の負荷とCPUの負荷、それぞれどこまで許容するかはじっくり検討することになります。
HUDで表示されているものは、ひとつひとつは小さくてすぐ作れそうに思われがちですが、ゲーム中のUI表示ほど難しいものはないと思います。世の中のアプリUI界隈では知見が共有されることも多くて楽しそうですが、あまりアクションゲームのHUDに関しては情報交換が活発じゃない気がします。 あくまでも想像ですが、HUDはデザインよりも機能性が重要視されるので、開発時はゲームプランナーやプログラマが主体となって実装されていくことが多いのがその理由かと思います。だいたいの仕様が見えてきてそろそろ体裁を整えてレビューしようとなった段階でデザイナーが呼ばれるのかなと。
というわけでみなさん、どんどん目コピーしましょう!
UE4はブループリントの触り方が分かってくれば、いろんなことが試せます。
いろいろ試して経験値が溜まってくればモックアップが自作できるようになります。それが動く指定書になって、プレゼンパワーが一気に上がります。うまくいけば実装に携われるようになります。そうなるとどんどんUIをアレンジしたり表現をリッチにできるかもしれません。
ではでは
今回はこの辺で
ステキなHUDライフを!