いつのまにか日も短くなって朝夕の冷え込みが堪える季節になってきました。今回はゲームUI制作のネタでもと思いたったので、キャラクターの絵をちょっと特殊な切り方で表示する方法を、架空のゲーム画面を制作する想定で書いていこうと思います。HUDなどのキャラ絵のバストアップをデザインのモックからテクスチャにしてUMGに持っていくあたりまで。
キャラの切り出し方について
テクスチャは四角です。四角く切って貼るのはデジタルではあたりまえです。ゆがむことはありません。そこに技術的な何かを感じられないとダメだ、という強迫観念のようなものと日々UIデザイナーたちは悪戦苦闘しているのではないでしょうか?
例えば、会話シーンなどでキャラの顔がフキダシと一緒に出る場合で、四角く切ってみたらこんな感じ。
確かに安定感はあります。翼や謎のブースターがついていても、問答無用でトリミングできるし、どんな絵でも確実に固定サイズできっちり揃えられる上に、アルファチャンネルを作りやすいです。
一方、スマブラのバトル画面で表示されている顔アイコンとか、ちょっと前に出たファイヤーエムブレムの風花雪月の会話ウィンドウでも見かけるやつがこんな感じ。
やっぱりきっちりと下敷きやフレームのカタチでカットされるより、少しはみ出した方が下敷きとの距離が出て立体的になるし、シルエットに変化が出るので、アホ毛やケモミミや角などでキャラ付けしてる場合は特に効果的です。さらに見た目に安っぽくならないのがいいのです。ただ作るのが若干手間だったりします。
前置きが長くなりましたが、このはみ出しタイプをPhotoshopで準備して、UE4のマテリアルで合成して、UMGでちゃっちゃと表示します。ただテクスチャ作って出してハイ終わり、だと面白くないので、架空のゲーム画面を作る体で進めます。
なので、先のチャットUI~の文体と被らないようにしてみたので、少々な感じの文体ですがそこは大目に見ていただけると幸いです。
RPGのバトル画面UIを作ることになった
お題として
- プラットフォームは未定だけど操作はマウスクリック
- 戦闘に出せるパーティーキャラは同時に4体まで
- 横画面で1920x1080
ひとまずキャラ絵の表示だけなら、これだけの情報でも作れなくはないけど、もう少し詳細がほしい。プランナーと話をする。
一緒に表示したいパラメータ
- キャラ名または職業名
- HPゲージ ※比率が分かる程度でよい
- SPゲージ(スキルポイント) ※比率が分かる程度でよい
- スキルアイコン ※チャージタイプ
で、この仕様をあれこれ考えてできたのがこんなレイアウト。
クリックできるものはナナメの◆。ただの情報は水平の ■ でルール化する。
背景の◆は半透明で、パーツをグルーピングするための要素で最終的には柄を入れたい。
これを、サイズ感を調整しながら4体分並べる。
ターン制という指示はないけど、チャージタイプの要素があるということはアクティブになったら即アクションというリアルタイム系のプレイスタイルだと思われるので、そのへんの仕様を考慮して3つの状態(初期・途中・最大)をデザインに織り込む。
アクティブの状態と非アクティブの状態が確実にわかるようにメリハリをつける。
今回、初期状態と最大の状態は同じ見た目ということにする。
チャージ中は、カウントアップの数字を出して待たせる。
この段階ではダメージを受けた時、スキル発動時なのどインタラクションは重要ではないので、いったんこれでプレゼンする。
レイアウトはOK出たので次は素材作成
無事プレゼンして了解が得られたところで、キャラ絵についてスケジュールを相談。
イラストレーターに発注するということで、作画のための仕様書を用意して渡すことにする。
いったん今回のレイアウトで決めたルールでキャラ絵のテクスチャを想定してみる。
サイズは256x256で行けそう。
そのテクスチャを基準にしてまとめると
ライトグリーンの領域を除いた部分が有効範囲。
それと併せて、
- バストアップ(全身は不要)
- カット領域は表示する際にカットする
- はみだし領域やカット領域については全キャラ共通
- ゲーム内でしか使わないので解像度はほどほどで
などの条件に加えて、レイアウト参考用のテンプレを作り依頼。
絵が上がってくるあいだに、アセットの準備を進める。
アセットをどう分けるかを考える。
キャラはフルカラーで透過が必要なので、256x256のRGBA各8bit 32bppのテクスチャ1枚。
背景の◆はどうするか?全キャラ共通でさらにマスクと共用できそうなので1枚。
計2枚あればなんとかなりそう。
◆のグラデもマテリアルで色を付けるくらいのシンプルさの方がキャラを引き立てられる。文様をいれてもいい。
キャラ絵はトリミングだけで済むので後で作るとして、キャラをカットするためのマスク用テクスチャから用意する。
下図のような3種類のマスクテクスチャを用意するんだけど、
これをR(#FF0000)G(#00FF00)B(#0000FF)の輝度としてレイヤー化。覆い焼きのリニアで加算することで1枚のテクスチャにできる。真っ黒(輝度が0)の部分は完全に透明になる。
色味が重要ではないので、それほど神経質になる必要はないけど、グラデーション機能を利用する場合は、滑らかさのパラメータ―を0%にしないと、リニアにならないので注意。
これをTGA形式 で書きだしたらUE4にインポートする。
圧縮するとエッジがガタガタになるので、Compression Settings は User Interface を選択。
- sRGBのチェックを外してリニアカラーにする
- タイリングは不要なので、Clamp を選択
- MipMapは必要無い
この設定でアセットにする。
マスク用のテクスチャができたところで、キャラ表示用のマテリアルを作成する。
ここは企画資料にあったラフ絵(PNGで抜いてあったから便利)で代用する。
サイズを調整して配置を決めたら、アルファチャンネルを作る。
まず抜きになっているレイヤーのサムネイルの上で、Ctrlキーを押しながらクリックすると、選択範囲が作られる。
そして、チャンネルパレットから 選択範囲の保存ボタンをクリックして作成完了。
本番のイラストがくれば差し替えるので、作業用Photoshopデータとして PSDで保存しておいてから、32bppの Targa(拡張子TGA)形式で書きだす。
UE4にインポートする。
マスク用のとほぼ同じ設定だけど、カラーはリニアではなくsRGBを有効にする。
テクスチャの準備ができたので、マテリアルを新しく作成。
UMGで使うので、MaterialDomainを User Interface に変更して、ついでに半透明も使えるようにする。
グラフにテクスチャのアセットアイコンをドラッグ&ドロップ。
先にTextureSampleノードを置く場合、テクスチャのSamplerTypeが合わないとエラーがでるので、手間を減らす意味でこのドラッグ&ドロップが便利。あとはいい感じに加算と掛け算を駆使。
キャラ絵は最終的にパラメータノードに差し替えるけど、今はこれで確認してみる。
UserWidgetを新しく用意。
UMGのキャンバスに256x256の Imageを配置する。
画像をセットする Brush のところにコンテンツブラウザからマテリアルアセットをドラッグ&ドロップする。
汎用性を持たせたいので、キャラをブループリントから差し替えられるようにする。
マテリアルを再び編集。
マテリアルパラメータ用のノードとして TextureSampleParameter2D を取り出す。
これと差し替える。
パラメータのノードには気持ち悪いサンプルのテクスチャがセットされているので、これをサイズの小さなブランクテクスチャを別途作って差し替えておきたい。
ブランク素材は差し替え前提の汎用アセットで、メモリにロードされた際に不要な参照を持たないようにするのが主な目的。プロジェクトで共通のアセットとして管理するのがベター。
ParameterDefaults というタブが用意されているので、そこからセットできる。
今回は 8x8の白色で、アルファチャンネルが0のテクスチャ。
これでマテリアルの編集は完了。
Widgetに戻ってブループリントを編集する。
マテリアルがうまくできているか確認するために、Event Pre Construct からパラメータにアクセスしてみる。
パラメータ名を None から 書き換えて、Value のところにキャラ絵のテクスチャアセットをセットしてコンパイルすると、キャンバスの状態が変わっているはず。試しに別のキャラ絵をインポートしてやってみる。
おなじ要領でサイズを調整してテクスチャにする。
大丈夫そうなので、マスクテクスチャを利用してドロップシャドウ的な下敷きもマテリアルで用意する。
このマテリアルも、キャラ絵と同じく Image の Brush にセットして使う。
あとはテキストやら、ゲージやらを置いていく。
レイアウトができた。
いまだに(4.23でも)UE4のフォントに付けられるアウトラインは、書体と表示するサイズによって欠けが発生する。フォントを手作りして頑張って回避してみるか、諦めてテクスチャにした方がいいと思う。けどテクスチャで数字のカウントを表示するのはひと手間かかるので何とかしてほしい。
ヒエラルキーはこんな感じ。
HPとSPゲージはマテリアルで色替えできるようにしておく。
今のところ、同じ仕様でただの色違いなので、マテリアルインスタンスでカラーバリエーションを作るようにする。
まずは、基本となる親マテリアル。
ゲージを増減させるための閾値を Scalar Parameter にして、ゲージ本体のカラーを Vector Parameter で受け取るようにする。
これができたら、コンテンツブラウザからこの親マテリアルうえで右クリックすると、マテリアルインスタンスが作成できる。
できたマテリアルインスタンスを開いてパラメータの部分を設定する。
このマテリアルインスタンスをUMGのImageパーツにあるセットするとゲージのできあがり。
親マテリアルとマテリアルインスタンスはサムネイルだけでは判別できないので、アセットアイコンの下線のカラーで見分けるようにする。
スキルアイコンは、少々特殊なゲージにしたかったのでマテリアルを専用で作る。
これは特にバリエーションがなさそうなので、マテリアルインスタンスは作らない。
BoxMask-2D というノードが用意されていたのでこれを使うことにする。
入力ピンのところに(V2)とあるので、Float型の値を2つまとめた Vector2 をつなぐ仕様になってるみたいだけど、Scalar でもエラーは出ない。
チャージ中と満タンの時でカラーを変えたいので、カラーを Vector Parameterにしておく。
あとは色味付けで、フォント用のグラデーションをマテリアルで用意する。これも汎用で使えそうなので、親を作って、マテリアルインスタンスでバリエーションを増やす。
このマテリアルを、TextBlockのフォントマテリアルのところにセットすると、文字にグラデーションがつく。
最後にスキルアイコン用マテリアル。
テクスチャは1024x1024の解像度に 80x80 のアイコンが 144種。職業によって覚えるスキルの数が変動するらしいけど、とりあえず、1職業につき最大10スキル。13職業ある想定。
ゲーム中にスキルの変更を手軽にできるようなことを聞いたので、常駐させる必要がある。サイズが大きくなるが、グレースケールテクスチャ(8bit)にするとテクスチャメモリが節約できる。
アイコン1個のサイズが 80px なので、 1024で割ると 0.078125
このマテリアルに スキルのID番号をパラメータとして渡してやる と、そのID番号のアイコンがトリミングされる仕組み。
表示するときにいくらか角度をつけて傾けているけど、斜めのままだとテクスチャ容量がもったいないので、Photoshopのスマートオブジェクトを使えば無理なく無駄なく詰めることができる。
表示範囲を示す赤いレイヤーを置いてその中にアイコンを置く。この状態で見た目を調整。テクスチャに持っていくとき、斜め角度を打ち消すように並べる。
スマートオブジェクトが中に持つピクセルは傾いたり回転していないので、編集する際はそのまま表示される見た目のままで作業できる。変形していても非破壊なのが素晴らしい。
だいたいのパーツは準備ができた。
あとは関数を用意して、キャラやスキルアイコンの差し替え、ゲージの更新などができるようになればかなり実用的になると思う。
というわけで、今回はこの辺でいったん終わりにします。続きは次回。
ではでは
ステキなキャラ顔表示ライフを!
おまけ
このネタを書こうと思い立った理由の一つに、キャラ絵をいかにキレイに表示するかというテクニックを解説している記事を見たことが無いから(個人調べ)というのがあります。
おそらくゲーム開発の現場で一子相伝の暗殺拳として子々孫々へと伝えられているのだろうと想像しています。実際そういったゲームUIの作り方なる秘伝のタレみたいなものがあればいいのですが、私自身ハードウェアの進化に付いていくために常に手探りしながら試行錯誤の毎日です。
で、今回の手法は、圧縮テクスチャを使わずに済むなら気にしなくてもいいのですが、圧縮される場合に特に効果的です。さらに、スマブラのように、状況によって背景のカラーを変えることができます。勢力違い、プレイヤー番号違いなど、同じキャラ絵でもバリエーションを安く量産できます。
また、圧縮するしないに関わらず、効果があるのが、シェーダーでまとめて重ねてしまうので、ピクセルシェーダー的には計算量が減るわけではないですが、表示パーツが少なくなるので、その分の処理を省くことができます。組み合わせるパーツのサイズやパラメータの扱い方によって変わるので確実に軽くなるとは言えないですが、試してみる価値は十分にあります。