みつまめ杏仁

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

キャラ絵のテクスチャを作って表示する《前編》

 いつのまにか日も短くなって朝夕の冷え込みが堪える季節になってきました。今回はゲームUI制作のネタでもと思いたったので、キャラクターの絵をちょっと特殊な切り方で表示する方法を、架空のゲーム画面を制作する想定で書いていこうと思います。HUDなどのキャラ絵のバストアップをデザインのモックからテクスチャにしてUMGに持っていくあたりまで。

 

キャラの切り出し方について

  テクスチャは四角です。四角く切って貼るのはデジタルではあたりまえです。ゆがむことはありません。そこに技術的な何かを感じられないとダメだ、という強迫観念のようなものと日々UIデザイナーたちは悪戦苦闘しているのではないでしょうか?

 

 例えば、会話シーンなどでキャラの顔がフキダシと一緒に出る場合で、四角く切ってみたらこんな感じ。

f:id:hiyokosabrey:20191120220846j:plain

 確かに安定感はあります。翼や謎のブースターがついていても、問答無用でトリミングできるし、どんな絵でも確実に固定サイズできっちり揃えられる上に、アルファチャンネルを作りやすいです。

 

 一方、スマブラのバトル画面で表示されている顔アイコンとか、ちょっと前に出たファイヤーエムブレムの風花雪月の会話ウィンドウでも見かけるやつがこんな感じ。

f:id:hiyokosabrey:20191120220753j:plain

 やっぱりきっちりと下敷きやフレームのカタチでカットされるより、少しはみ出した方が下敷きとの距離が出て立体的になるし、シルエットに変化が出るので、アホ毛やケモミミや角などでキャラ付けしてる場合は特に効果的です。さらに見た目に安っぽくならないのがいいのです。ただ作るのが若干手間だったりします。

 

 前置きが長くなりましたが、このはみ出しタイプをPhotoshopで準備して、UE4のマテリアルで合成して、UMGでちゃっちゃと表示します。ただテクスチャ作って出してハイ終わり、だと面白くないので、架空のゲーム画面を作る体で進めます。 

  なので、先のチャットUI~の文体と被らないようにしてみたので、少々な感じの文体ですがそこは大目に見ていただけると幸いです。

 

RPGのバトル画面UIを作ることになった

お題として

  • プラットフォームは未定だけど操作はマウスクリック
  • 戦闘に出せるパーティーキャラは同時に4体まで
  • 横画面で1920x1080

ひとまずキャラ絵の表示だけなら、これだけの情報でも作れなくはないけど、もう少し詳細がほしい。プランナーと話をする。

一緒に表示したいパラメータ

  • キャラ名または職業名
  • HPゲージ ※比率が分かる程度でよい
  • SPゲージ(スキルポイント) ※比率が分かる程度でよい
  • スキルアイコン ※チャージタイプ

で、この仕様をあれこれ考えてできたのがこんなレイアウト。

f:id:hiyokosabrey:20191117122440p:plain

クリックできるものはナナメの◆。ただの情報は水平の ■ でルール化する。

背景の◆は半透明で、パーツをグルーピングするための要素で最終的には柄を入れたい。

これを、サイズ感を調整しながら4体分並べる。

f:id:hiyokosabrey:20191117123031p:plain

ターン制という指示はないけど、チャージタイプの要素があるということはアクティブになったら即アクションというリアルタイム系のプレイスタイルだと思われるので、そのへんの仕様を考慮して3つの状態(初期・途中・最大)をデザインに織り込む。

f:id:hiyokosabrey:20191117124223p:plain


アクティブの状態と非アクティブの状態が確実にわかるようにメリハリをつける。

今回、初期状態と最大の状態は同じ見た目ということにする。

チャージ中は、カウントアップの数字を出して待たせる。

この段階ではダメージを受けた時、スキル発動時なのどインタラクションは重要ではないので、いったんこれでプレゼンする。

 

レイアウトはOK出たので次は素材作成

無事プレゼンして了解が得られたところで、キャラ絵についてスケジュールを相談。

イラストレーターに発注するということで、作画のための仕様書を用意して渡すことにする。

いったん今回のレイアウトで決めたルールでキャラ絵のテクスチャを想定してみる。

サイズは256x256で行けそう。

そのテクスチャを基準にしてまとめると

f:id:hiyokosabrey:20191117133044p:plain

ライトグリーンの領域を除いた部分が有効範囲。

それと併せて、

  • バストアップ(全身は不要)
  • カット領域は表示する際にカットする
  • はみだし領域やカット領域については全キャラ共通
  • ゲーム内でしか使わないので解像度はほどほどで

などの条件に加えて、レイアウト参考用のテンプレを作り依頼。

 

f:id:hiyokosabrey:20191117135553p:plain

 

絵が上がってくるあいだに、アセットの準備を進める。

 

アセットをどう分けるかを考える。

キャラはフルカラーで透過が必要なので、256x256のRGBA各8bit 32bppのテクスチャ1枚。

背景の◆はどうするか?全キャラ共通でさらにマスクと共用できそうなので1枚。

 

f:id:hiyokosabrey:20191117142952p:plain

 

計2枚あればなんとかなりそう。

◆のグラデもマテリアルで色を付けるくらいのシンプルさの方がキャラを引き立てられる。文様をいれてもいい。

 

キャラ絵はトリミングだけで済むので後で作るとして、キャラをカットするためのマスク用テクスチャから用意する。

 

下図のような3種類のマスクテクスチャを用意するんだけど、

 

f:id:hiyokosabrey:20191117154851p:plain

 

これをR(#FF0000)G(#00FF00)B(#0000FF)の輝度としてレイヤー化。覆い焼きのリニアで加算することで1枚のテクスチャにできる。真っ黒(輝度が0)の部分は完全に透明になる。

 

f:id:hiyokosabrey:20191117155107p:plain

 

色味が重要ではないので、それほど神経質になる必要はないけど、グラデーション機能を利用する場合は、滑らかさのパラメータ―を0%にしないと、リニアにならないので注意。

 

f:id:hiyokosabrey:20191117180033p:plain


これをTGA形式 で書きだしたらUE4にインポートする。

 

圧縮するとエッジがガタガタになるので、Compression Settings は User Interface を選択。

f:id:hiyokosabrey:20191117180915p:plain

  •  sRGBのチェックを外してリニアカラーにする
  • タイリングは不要なので、Clamp を選択
  • MipMapは必要無い

この設定でアセットにする。

 

マスク用のテクスチャができたところで、キャラ表示用のマテリアルを作成する。

ここは企画資料にあったラフ絵(PNGで抜いてあったから便利)で代用する。

サイズを調整して配置を決めたら、アルファチャンネルを作る。

f:id:hiyokosabrey:20191117200738p:plain

まず抜きになっているレイヤーのサムネイルの上で、Ctrlキーを押しながらクリックすると、選択範囲が作られる。

f:id:hiyokosabrey:20191117201316p:plain

f:id:hiyokosabrey:20191117201740g:plain

そして、チャンネルパレットから 選択範囲の保存ボタンをクリックして作成完了。

f:id:hiyokosabrey:20191117202416p:plain

f:id:hiyokosabrey:20191117202845p:plain

本番のイラストがくれば差し替えるので、作業用Photoshopデータとして PSDで保存しておいてから、32bppの Targa(拡張子TGA)形式で書きだす。

f:id:hiyokosabrey:20191117202623p:plain

 

UE4にインポートする。

マスク用のとほぼ同じ設定だけど、カラーはリニアではなくsRGBを有効にする。

f:id:hiyokosabrey:20191117203408p:plain

 

テクスチャの準備ができたので、マテリアルを新しく作成。

f:id:hiyokosabrey:20191117204707p:plain

 

UMGで使うので、MaterialDomainを User Interface に変更して、ついでに半透明も使えるようにする。

f:id:hiyokosabrey:20191117203823p:plain

 

グラフにテクスチャのアセットアイコンをドラッグ&ドロップ。

f:id:hiyokosabrey:20191117204720p:plain

先にTextureSampleノードを置く場合、テクスチャのSamplerTypeが合わないとエラーがでるので、手間を減らす意味でこのドラッグ&ドロップが便利。あとはいい感じに加算と掛け算を駆使。

f:id:hiyokosabrey:20191117205452p:plain

キャラ絵は最終的にパラメータノードに差し替えるけど、今はこれで確認してみる。

 

UserWidgetを新しく用意。

f:id:hiyokosabrey:20191117210603p:plain

 

UMGのキャンバスに256x256の Imageを配置する。

f:id:hiyokosabrey:20191117210202p:plain

画像をセットする Brush のところにコンテンツブラウザからマテリアルアセットをドラッグ&ドロップする。

f:id:hiyokosabrey:20191117210338p:plain

f:id:hiyokosabrey:20191117210426p:plain

汎用性を持たせたいので、キャラをブループリントから差し替えられるようにする。

マテリアルを再び編集。

マテリアルパラメータ用のノードとして TextureSampleParameter2D を取り出す。

f:id:hiyokosabrey:20191117211234p:plain

f:id:hiyokosabrey:20191117211333p:plain

これと差し替える。

f:id:hiyokosabrey:20191117211754p:plain

パラメータのノードには気持ち悪いサンプルのテクスチャがセットされているので、これをサイズの小さなブランクテクスチャを別途作って差し替えておきたい。

ブランク素材は差し替え前提の汎用アセットで、メモリにロードされた際に不要な参照を持たないようにするのが主な目的。プロジェクトで共通のアセットとして管理するのがベター。

ParameterDefaults というタブが用意されているので、そこからセットできる。

f:id:hiyokosabrey:20191117212536p:plain

今回は 8x8の白色で、アルファチャンネルが0のテクスチャ。

これでマテリアルの編集は完了。

 

Widgetに戻ってブループリントを編集する。

マテリアルがうまくできているか確認するために、Event Pre Construct からパラメータにアクセスしてみる。

f:id:hiyokosabrey:20191117213643p:plain

パラメータ名を None から 書き換えて、Value のところにキャラ絵のテクスチャアセットをセットしてコンパイルすると、キャンバスの状態が変わっているはず。試しに別のキャラ絵をインポートしてやってみる。

f:id:hiyokosabrey:20191117214717p:plain

おなじ要領でサイズを調整してテクスチャにする。

f:id:hiyokosabrey:20191117215541p:plain

大丈夫そうなので、マスクテクスチャを利用してドロップシャドウ的な下敷きもマテリアルで用意する。

f:id:hiyokosabrey:20191117220508p:plain

このマテリアルも、キャラ絵と同じく Image の Brush にセットして使う。

f:id:hiyokosabrey:20191117220659p:plain

あとはテキストやら、ゲージやらを置いていく。

 

レイアウトができた。

f:id:hiyokosabrey:20191121203922p:plain

いまだに(4.23でも)UE4のフォントに付けられるアウトラインは、書体と表示するサイズによって欠けが発生する。フォントを手作りして頑張って回避してみるか、諦めてテクスチャにした方がいいと思う。けどテクスチャで数字のカウントを表示するのはひと手間かかるので何とかしてほしい。

 

ヒエラルキーはこんな感じ。

f:id:hiyokosabrey:20191123133054p:plain


 

HPとSPゲージはマテリアルで色替えできるようにしておく。

f:id:hiyokosabrey:20191121205224p:plain

今のところ、同じ仕様でただの色違いなので、マテリアルインスタンスでカラーバリエーションを作るようにする。
まずは、基本となる親マテリアル。

f:id:hiyokosabrey:20191121205703p:plain

ゲージを増減させるための閾値を Scalar Parameter にして、ゲージ本体のカラーを Vector Parameter で受け取るようにする。

 

これができたら、コンテンツブラウザからこの親マテリアルうえで右クリックすると、マテリアルインスタンスが作成できる。

f:id:hiyokosabrey:20191121205801p:plain

 

できたマテリアルインスタンスを開いてパラメータの部分を設定する。

f:id:hiyokosabrey:20191121210345p:plain

このマテリアルインスタンスをUMGのImageパーツにあるセットするとゲージのできあがり。

親マテリアルとマテリアルインスタンスはサムネイルだけでは判別できないので、アセットアイコンの下線のカラーで見分けるようにする。

f:id:hiyokosabrey:20191121211115p:plain

 

スキルアイコンは、少々特殊なゲージにしたかったのでマテリアルを専用で作る。

これは特にバリエーションがなさそうなので、マテリアルインスタンスは作らない。

f:id:hiyokosabrey:20191121211813p:plain

BoxMask-2D というノードが用意されていたのでこれを使うことにする。

f:id:hiyokosabrey:20191121212017p:plain

入力ピンのところに(V2)とあるので、Float型の値を2つまとめた Vector2 をつなぐ仕様になってるみたいだけど、Scalar でもエラーは出ない。

チャージ中と満タンの時でカラーを変えたいので、カラーを Vector Parameterにしておく。

 

あとは色味付けで、フォント用のグラデーションをマテリアルで用意する。これも汎用で使えそうなので、親を作って、マテリアルインスタンスでバリエーションを増やす。

f:id:hiyokosabrey:20191121214713p:plain

このマテリアルを、TextBlockのフォントマテリアルのところにセットすると、文字にグラデーションがつく。

f:id:hiyokosabrey:20191121215443p:plain

 

最後にスキルアイコン用マテリアル。

f:id:hiyokosabrey:20191121220305p:plain

テクスチャは1024x1024の解像度に 80x80 のアイコンが 144種。職業によって覚えるスキルの数が変動するらしいけど、とりあえず、1職業につき最大10スキル。13職業ある想定。

ゲーム中にスキルの変更を手軽にできるようなことを聞いたので、常駐させる必要がある。サイズが大きくなるが、グレースケールテクスチャ(8bit)にするとテクスチャメモリが節約できる。

f:id:hiyokosabrey:20191121225943p:plain

 アイコン1個のサイズが 80px なので、 1024で割ると  0.078125

f:id:hiyokosabrey:20191121230717p:plain

このマテリアルに スキルのID番号をパラメータとして渡してやる と、そのID番号のアイコンがトリミングされる仕組み。

 

表示するときにいくらか角度をつけて傾けているけど、斜めのままだとテクスチャ容量がもったいないので、Photoshopのスマートオブジェクトを使えば無理なく無駄なく詰めることができる。

f:id:hiyokosabrey:20191121232157p:plain

表示範囲を示す赤いレイヤーを置いてその中にアイコンを置く。この状態で見た目を調整。テクスチャに持っていくとき、斜め角度を打ち消すように並べる。

f:id:hiyokosabrey:20191121232541p:plain

スマートオブジェクトが中に持つピクセルは傾いたり回転していないので、編集する際はそのまま表示される見た目のままで作業できる。変形していても非破壊なのが素晴らしい。

 

だいたいのパーツは準備ができた。

あとは関数を用意して、キャラやスキルアイコンの差し替え、ゲージの更新などができるようになればかなり実用的になると思う。

 

というわけで、今回はこの辺でいったん終わりにします。続きは次回。

 

ではでは

ステキなキャラ顔表示ライフを!

 

 

 

 

 


 おまけ

 このネタを書こうと思い立った理由の一つに、キャラ絵をいかにキレイに表示するかというテクニックを解説している記事を見たことが無いから(個人調べ)というのがあります。

 おそらくゲーム開発の現場で一子相伝暗殺拳として子々孫々へと伝えられているのだろうと想像しています。実際そういったゲームUIの作り方なる秘伝のタレみたいなものがあればいいのですが、私自身ハードウェアの進化に付いていくために常に手探りしながら試行錯誤の毎日です。

 で、今回の手法は、圧縮テクスチャを使わずに済むなら気にしなくてもいいのですが、圧縮される場合に特に効果的です。さらに、スマブラのように、状況によって背景のカラーを変えることができます。勢力違い、プレイヤー番号違いなど、同じキャラ絵でもバリエーションを安く量産できます。

 また、圧縮するしないに関わらず、効果があるのが、シェーダーでまとめて重ねてしまうので、ピクセルシェーダー的には計算量が減るわけではないですが、表示パーツが少なくなるので、その分の処理を省くことができます。組み合わせるパーツのサイズやパラメータの扱い方によって変わるので確実に軽くなるとは言えないですが、試してみる価値は十分にあります。