UMGに関する情報は分散していて、なかなか教科書的な使い方がわからないものです。ここでは9Slice,GetUserInterfaceUVなどを使い、プロシージャルな手法で作成したマテリアルと組み合わせて汎用性の高いボタンを作成することを目指します。

要件

  1. サイズ毎に部品を作る必要を減らすためリサイズ可能であること
  2. 解像度依存を減らすためにテクスチャを減らすこと
  3. ボタンアニメーションを調整しやすい形で実装すること

これらの開発現場での要求に即した作り方をまとめてみました。

作例

今回は角丸あり、枠線ありの矩形ボタンを作成することにします。同様の手法でどのような形状が作れるか・または作れないか、は別途検討します。

マテリアル

要件1と2を満たすことのできるマテリアルはプロシージャルな手法で作成することになります。9Sliceを利用することを想定して正方形を4分割し、それぞれをボタンフレームの4角として割り当てるように見た目を形成します。この際、肝になるのは下記の2点です。

  • 角丸の半径と枠線の太さを設定できるScalarParameterを用意する
    • raduis・・・角丸の半径
    • thickness・・・枠線の太さ
  • UVについてはGetUserInterfaceUVから取得する
    • ピン「9-Slice UV」は9Slice設定を反映したUVが導かれる
    • ピン「NormalizedUV」は9Slice設定を無視したUVが導かれる

WidgetBPデザイナー画面:Imageパネル

ウィジェットブループリントでのImageパネルの設定は下記のように行います。「アピアランス」のDrawAsをBoxとして、Margin値とImageSize値にて9Sliceの設定を行います。各値の設定値に癖があるので図解しました。

ボタンテキストの設定

要件1にあるリサイズ可能性を維持するため、テキストのフォントサイズもボタンサイズに合った形で拡縮するような配置を検討します。フォントサイズ値を随時変更するのはあまり現実的ではないのでScaleBoxパネルを利用してみます。

WBP_Btnと名付けたユーザーウィジェットは下記のような階層と設定を持つようにしました。

上図の設定により、このユーザーウィジェットをCanvasPanel等に配置した親ウィジェットでサイズ指定を行うと、そのサイズに沿ったボタン形状やフォントサイズに変更されます。

【留意点】UEのフォントはサイズが変更されるごとにメモリにそのサイズ用のフォントテクスチャが展開されるらしい?のでメモリ量には気を付ける必要があるかもしれません。

テキストのオーバーライド設定

ボタン関連のワークフローでいうと、ボタン内の可変内容物(テキストやアイコンなど)をどのようにプログラムとやり取りするか、という問題が常に存在します。

UE以外のエンジンではボタン部品の内部オブジェクトを部品を配置した親レイアウトから上書き(オーバーライド)する機能を持たせ、親レイアウトの各ボタンインスタンスでテキストを設定させるのが一般的な様に思います。ただUEではその機能は明示的に紹介されておらず、NamedSlotパネルなどの代替方法を紹介されるのですが、これはテキストアニメーションとは相性が悪くこの場合には向きません。

結局プログラマに直接対象のオブジェクトをスコープしてテキスト代入してもらうことになることが多いのではないかと思いますが、ここでは別の方法を紹介します。(ただパフォーマンスの懸念もあるのでその懸念を併記しておきます)

WBP_Btnボタン内に一つのテキストPanelであるtxt_valueを持つとして、グラフ画面にて新たにText型の変数txtValueを作成します(名称は何でも良い)。インスタンス編集可能設定を行い(もしくは変数の右端の目マークを開かせる)外部から編集可能にします。

Text型変数txtValueの作成と設定

デザイナー画面にもどり、テキストボックスのテキスト設定右の「バインド」プルダウンに先ほど作成したtxtValueが選択肢に追加されるので、これを選択します。

テキストバインドの設定

このボタンを配置した親部品に配置すると、その設定項目「デフォルト」に先ほど設定したtxtValueの項目が表示されるので、ここでボタンインスタンスごとにテキストを設定することが可能になります。

親レイアウトのインスタンス毎にtxtValueを上書き設定できる
実行するとボタンテキストが設定したtxtValueに差し変わっているのがわかる

ただし、この「バインド」を使う方法は毎フレーム処理が走る、ということから基本的に非推奨であるという認識があります。

今回は単にテキスト変数を呼んでいるだけなので、そこまでパフォーマンスに影響を与えるかは調べてみないとわかりませんが、このワークフロー上有意義な仕組みを採用するか、プログラマと相談する価値があるのではないかと思います。

後編はボタンアニメーションなどについて触れていく予定です。