読者です 読者をやめる 読者になる 読者になる

みつまめ杏仁

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

キャラセレを作ってみる 素材編

UE4のUMGでUIライフを楽しんでおられる紳士淑女の皆様いかがお過ごしでしょうか。

久しぶりにガッツリとUI画面でも作ってみようかな~と、思い立って準備を進めてみたものの結構かかってしまった。ゲームにはつきもの、キャラクターセレクト画面を作ってみようと思います。

 で、なんとなくレイアウトしてみたのがコレ↓

f:id:hiyokosabrey:20170522001101j:plain

自分のヘタなイラストを用意して並べると公開するまで何光年かかるかわからないので、いらすとや さんの素材使わせてもらいました。怒られたらゴメンナサイします。

動きはカーソルを動かすたびに画面左の大きいキャラ絵が、フォーカスしているキャラ絵に入れ替わります。同時に能力を比較するグラフを更新します。

今回は素材編ということで、素材を用意するとこまでを説明します。

少しづつ機能を追加しながら説明をしてゆこうと思うので続きが気になる方は、

ぜひ いいね ボタンをクリックしてください。(冗談です)

 

素材を準備

キャラセレは登場するキャラクターが多いほど準備が大変ですが、

まずは画面を構成するために用意する素材は以下の7種類。

  1. 背景
  2. 見出し(画面タイトル)
  3. 選択用のキャラクターサムネイル
  4. カーソル
  5. フォーカスしている状態の大きいキャラクターイラスト
  6. キャラクターの名前
  7. キャラ性能グラフ(おまけ)

 

まずは絵素材を用意するところから始めます。

1. 背景

サイズは今回 1920x1080 のフルHDで用意しました。

f:id:hiyokosabrey:20170522002206j:plain

動きはなくてシンプルな1枚絵です。

 

2. 見出し(画面タイトル)

透過の状態で、テクスチャ化します。

f:id:hiyokosabrey:20170522002715j:plain

透過(透明度情報)をアルファチャンネルとして扱えるフォーマットならOK。

Photoshop形式もOKですが、個人的にレイヤーを統合していないPhotoshopのラスタライズ画像は信用していないので、PNGとかTGA(Targa)をオススメします。アルファチャンネルを透過として扱わない場合があることを考えると、やっぱり汎用性が高くて可逆圧縮なTGAが最適かなと思う今日この頃です。

 

3.選択用のキャラクターサムネイル

キャラクターの部分をトリミングしてサムネイルにします。

キャラクター1体が  256x256 です。

 f:id:hiyokosabrey:20170522003947j:plain

でアルファチャンネルを下図のようにしました。

f:id:hiyokosabrey:20170522004120p:plain

レイヤー上でくり抜いてしまうと、後から調整が面倒になるのでこのような構成にしています。レイヤーマスクを使うのもありです。これができるからPhotoshopが手放せないんですよね。

アルファチャンネルの白い部分が、見た目のカタチになります。

f:id:hiyokosabrey:20170522004828j:plain

 

4.カーソル

サムネイルの形に合わせてデザインします。

f:id:hiyokosabrey:20170522005754p:plain

これも重ねて使うので透明部分があります。

 

5.フォーカスしている状態の大きいキャラクターイラスト

なるべく大きい絵でキャラクターを魅力的にみせたいものです。

f:id:hiyokosabrey:20170522151443j:plain

これも透過で作成します。表示した際に少し浮き出た感じにしたいので、レイヤー効果の「ドロップシャドウ」を使っています。

この見た目でアルファチャンネルを作るときアナタならどうしますか?

スタイルをラスタライズすればドロップシャドウの分のピクセルが選択範囲として取れますが、アンドゥ―で戻すか、レイヤーを複製してからじゃないと元の状態を維持できないので面倒です。実はPhotoshopには隠しショートカットキーがいくつかあります。

そのなかでも便利なのが Ctrl + Alt + Shift を押しながら E キーです。

f:id:hiyokosabrey:20170522153506p:plain

状態によっては新規レイヤーが必要ない場合もありますが、ここでショートカットキーの出番です。すると、表示されている状態を結合した状態で新規レイヤーにラスタライズしてくれます。

f:id:hiyokosabrey:20170522153803p:plain

どれだけレイヤーが重なっていようが、レイヤー効果がかかっていようが、問答無用に表示状態が1枚のレイヤーにまとまるので、アルファチャンネルを抽出するのがものすごくラクちんになります。あとは、レイヤーのサムネイルを Ctrl キーを押しながらクリックするだけで選択範囲が取れるので、そのままアルファチャンネルを作成できます。アルファチャンネルが取れて用が済んだらこのレイヤーは削除するのをお忘れなく。

f:id:hiyokosabrey:20170522221533j:plain

アルファチャンネルが作れたら、背景を表示してテクスチャとして書き出します。

f:id:hiyokosabrey:20170522154958p:plain

エルフアーチャーかわいいなあ。

 

6.キャラクターの名前

キャラクターの名前は別のテクスチャにまとめます。これは演出の都合もありますが、デザインの調整がラクなのと、あとから名前が変わったりするからです。最近は手軽にワールドワイド向けのゲームが販売できる時代なので、ローカライズの手間を考えると別にしておくと差し替えが簡単です。

f:id:hiyokosabrey:20170522155650j:plain

これも透過で、作り方はキャラ絵と同じです。

 

7のキャラ性能グラフはちょっと特殊なので後日説明記事とともに載せます。

 

素材は以上です。

次回はWidgetを作成していきます。

では今回はここまで。

 

 

 

マクロライブラリを作る

f:id:hiyokosabrey:20170508012221p:plain

 

久しぶりです、大丈夫まだ生きてます。

UIの画面を作っていると、「あとはカーソルを動かせれば完成なのに・・・」「パッドのトリガーでページ切り替えしたい・・・」「ウィンドウを閉じたり開いたりしたい・・・」「Xボタンを押しながらだとスクロールができて・・・」などなど、実際に動かして確認したくなります。

UIはユーザーが操作するからUIであるということで、キー操作を受け付ける動作が必須です。そのあたりの処理は、ブループリントマクロライブラリを作ることで面倒なキー入力周りの処理が一気にラクになります。プロジェクトに一つ置いておけば、どのブループリントからでも簡単に利用できます。

f:id:hiyokosabrey:20170508000939p:plain

同じようなキー入力処理をやるためのしくみを、ちょうど一年前に書いていました。

limesode.hatenablog.com

この時は親クラスを先に作って、そこから子クラスを作る流れでした。

それなりに手数が必要になります。

今回はクラスとか気にせず気軽にキー入力周りを扱うためのマクロを作ります。

これは使いたいときにどのブループリントでも呼び出して使うことができます。

 

作ってみる

まずコンテンツブラウザで右クリックして、

Blueprints > Blueprint Macro Library を選択します。

 

f:id:hiyokosabrey:20170507224049p:plain

 ダイアログが出てくるので、

f:id:hiyokosabrey:20170507225754p:plain

Object をフォーカスしてからOKボタンを押します。

 アイコンが出てきたら名前を付けてやります。この名前はただのアセット名なので後でなんのために作ったかわかるようになっていればなんでもOK。マクロライブラリ自体がいろんなブループリントから参照されるので、UI_Common とかでいいかなと思います。

名前を付けたらアイコンをダブルクリックして編集開始です。

 エディタが開くと下のような形になっているので、まずは右上のフォームからマクロの名前を入力します。

f:id:hiyokosabrey:20170507225731p:plain

この名前がノードとして扱われることになります。右上の + ボタンでいくつでもマクロを追加できます。

今回、UI_InputCheckSimple という名前で進めます。

 

引数(パラメータ)をセット

レベルブループリント以外でInputノードが使えないので、キー入力を受け取るためには、Was Input Key Just Pressed ノードを使います。

これは get Player Controller ノードから値をもらわないと働いてくれないので、まずは Player Controller型 のマクロの引数(Inputパラメータ)を追加します。

f:id:hiyokosabrey:20170507231129p:plain

 最後じゃなくてもいいので、名前は必ず変更するようにします。

f:id:hiyokosabrey:20170507231727p:plain

 

 

どんどんつなぐ

 そこからドラッグして Was Input Key Just Pressed ノードを取り出します。

f:id:hiyokosabrey:20170507231925p:plain

このノードのKeyの横にあるプルダウンから押したかどうかを検出する対象を選びます。で、ブール値(true か false)の出てくる赤いピンがあるので、そこからブランチノードをつなぎます。(ブランチノードはキーボードの[ B ]を押しながらクリックすると取り出すのがラクチンです)

f:id:hiyokosabrey:20170507232134p:plain

実行ピンがまだつながっていないので、ブランチノードからドラッグして、Inputsノードの上でドロップします。ドロップ場所に気をつけて、いい感じにドロップするとうまくつながります。

f:id:hiyokosabrey:20170507232853p:plain

後からのものは下に足されていくので、順番が気になる場合は変更します。Inputsノードを選択している状態で、Detailsタブの中にある項目から変更できます。

f:id:hiyokosabrey:20170507233208p:plain

 

これを1セットとして、

ブランチノードの false から次の Was Input Key Just Pressed ノードへ、数珠繋ぎになるようにつないでいきます。

f:id:hiyokosabrey:20170507233516p:plain

 一通りつないだら、true のピンを Outputsノードにつないでいきます。

さっきやったドラッグ&ドロップが便利です。

f:id:hiyokosabrey:20170507234130p:plain

なるべくわかりやすいピン名にしておきます。

f:id:hiyokosabrey:20170507234605p:plain

でき上がりです。

上・下・左・右・決定 を検出できるようになります。

これをコンパイルしてエラーが無ければ保存して閉じます。

 

使い方

使いたいブループリントの Tick ノードにつないで使います。

同じプロジェクト内であればどこでも呼び出すことができます。

↓サンプル

f:id:hiyokosabrey:20170507235543p:plain

マクロを作成する際にインスタンスカラーというのが設定できます。キー入力イベント関連なのでノードに赤色を付けてみました。

f:id:hiyokosabrey:20170507235954p:plain

 

 

次回以降

このマクロを使って、キャラセレ画面を作ってみる記事を書こうと思います。

ではでは~

 

 

 

UE4のテキスト効果

相変わらず記事を書く時間が取れないまま4月ですよ。ニューカマー達が押し寄せてきてます。すぐそこに!

というわけで、ぷちネタを思いついたので、書いておきます。

もう誰かがやってそうですが・・・・

なんとUE4の最新バージョンで

Widgetのテキストブロックに、ソフトなドロップシャドウが! さらにグロー処理も!

f:id:hiyokosabrey:20170409015154p:plain

 

 

・・・

実はこれ、エイプリルフール向けのネタとして準備していたものです。

種明かしをすると、Ver 4.15から実装された、Background Blur パネル を使用しています。

シャドウとグロー用のテキストブロックを置きます。

f:id:hiyokosabrey:20170409020510p:plain

そこに Background Blurパネルを重ねます。

f:id:hiyokosabrey:20170409020518p:plain

仕上げにテキストブロックを重ねて完成です。

f:id:hiyokosabrey:20170409015154p:plain

大したネタではないですね。すみません。

 

この方法はあくまでも背景がシンプルな単色だからできる方法です。

テクスチャで表現する方法だと、テキストの変更に合わせるのは大変です。

使いどころは限られますが、うまく使える場面はきっとあると思います。

 

今回は短いですがそろそろ寝ます。

ではでは

ステキなWidgetライフを!

 

 

はみ出た文字のサイズを調整

久しぶりの更新。なかなか記事を書く時間がないので困ったものです。

NintendoSwitchにもUE4が対応するということで、どんなゲームUIが出てくるか楽しみです。

さてさて以前テキストに合わせてフキダシの大きさを変えるのを書きましたが、今回は逆に決められたサイズを越えたら無理やり収めるというのを書いてみようかと。

UMGのテキストブロックには、Size to Content という設定があって、これを有効にすると中身に合わせてサイズが可変するというしくみが用意されています。

f:id:hiyokosabrey:20170319020555p:plain

 

まずはSize To Content にチェックを付けたテキストブロックを3つ並べてみます。

f:id:hiyokosabrey:20170319020110p:plain

ちょっと実験したいので、それぞれ文字詰めの方向を変えています。

f:id:hiyokosabrey:20170319021500p:plain

 

ブループリントから文字を流し込んでみます。

setTextノードを使います。

f:id:hiyokosabrey:20170319021924p:plain

適当な文字を仕込んでPlayしてみると・・・

f:id:hiyokosabrey:20170319022537p:plain

配置した Text Block のポジションから流し込まれて、見た目に差はでません。

 

文字詰めの指定をしても、エンジンが気を利かせてくれるわけではないようです。

残念。

試しに複数行のテキストを流し込んでみます。

f:id:hiyokosabrey:20170319023805p:plain

文字のサイズを小さくしています。

横の一番長いテキストに合わせてきちんと文字詰めされていることが分ります。

 テキストの長さ次第でレイアウトが安定しないのはちょっと使いづらい感じです。

 

さてさて、気を取り直して、

まずはテキストブロックのサイズを取得する処理を用意します。

基準点を指定して、そこにセンタリングする関数を作りました。

センタリングの仕組みを簡単に図にしてみました。

f:id:hiyokosabrey:20170321003611p:plain

 

 テキストブロックにテキストをセットした後に呼び出します。

f:id:hiyokosabrey:20170321001706p:plain

 

こんな感じになりました。同じ内容ですがバラバラのテキストブロックです。

f:id:hiyokosabrey:20170319220803p:plain

 

この辺で長さの違うテキストを表示してみます。

 大好きなゲームから拝借。

f:id:hiyokosabrey:20170321005407p:plain

 これを、はみ出たやつだけ縮小すようにします。

センタリング処理の関数に追加します。

f:id:hiyokosabrey:20170321010653p:plain

 

でPlayしてみると・・・

f:id:hiyokosabrey:20170321010914p:plain

いい感じに収まってくれました。

 

フォントの形がおかしくなるので、あまりやらない方がいいのですが、

表示したいテキストのうち、ほんの少しくらいならこういった縮小処理は画面レイアウトを維持するためには積極的に使っていきたいものです。

 

ではでは今回はこの辺で

 

 

テキストブロックのスクロール 続き

前回の続きでスクロールバーを付けてみます。

limesode.hatenablog.com

 以外にサクッとできました。まずはUMGのパーツを追加するところから。

 

f:id:hiyokosabrey:20170220223725p:plain

スクロールバー全体の大きさを決めるキャンバスパネルを親にして、スクロールバーの下敷きとバー本体を表すImageパーツを子供にします。ちょっとだけラクをしたいのでバーの長さは、テキストブロックの表示サイズと同じにしています。

 

スクロールバーの長さを計算して変更する関数を追加します。

f:id:hiyokosabrey:20170220224608p:plain

このセットアップ関数は、テキストブロックの中身を変更する関数の中に置きます。

f:id:hiyokosabrey:20170220224816p:plain

スクロールバーを動かすためのマクロを用意。

f:id:hiyokosabrey:20170220225243p:plain

これをテキストボックスのスクロール部分にくっつけます。

f:id:hiyokosabrey:20170220230103p:plain

テキストボックスを動かす計算をしたあと、その値を拝借するカタチです。

以上で完成です。

 

不思議の国のアリス(英語)の冒頭を使って試してみました。

f:id:hiyokosabrey:20170220230446p:plain

f:id:hiyokosabrey:20170220230458p:plain

やっぱりスクロールバーはいいですね。あとどのくらいっていうのが判るのは大事です。

UMGにはとても便利な 『スクロールボックス』 が既に用意されているので、わざわざ苦労して作ることもないのですが・・・ こういった基本的なUIを自分の手で一回は作っておくのもいいと思います。試行錯誤してみて初めて仕組みの深いところが分かったり、当たり前のように毎日使ってるGUIの奥深さに気付くこともあるかと。

 

ではでは今回はこの辺で

ステキなスクロールライフを!

 

 

テキストブロックのスクロール

f:id:hiyokosabrey:20170218200852p:plain

 テキストブロックで、長文を表示しようとしたときに、たいていAuto Wrap Text(=自動改行)にすると思います。

f:id:hiyokosabrey:20170218203113p:plain

文字量が多いとサイズが大きくて表示しきれないので、スクロールさせるのが我々UI業界では当たり前の仕組みです。

 

UMG パーツ

f:id:hiyokosabrey:20170218220855p:plain

 まずはイイ感じの大きさのキャンバスパネルを置いて、その子供にテキストブロックとイメージを配置します。キャンバスは表示範囲を限定するためのものです。子供たちにとってこのキャンバスパネルが実際に表示される大きさになるので、アンカーの設定を右下のやつに設定します。

f:id:hiyokosabrey:20170218221511p:plain

スロットの設定は以下のようにすると、親のキャンバスパネルにピッタリフィットするように可変します。

f:id:hiyokosabrey:20170218221818p:plain

 Offset ~ は余白が欲しい時に設定します。

 

Event Construct

事前に取得できて後から再利用できる値は、なるべく変数化しておきます。

f:id:hiyokosabrey:20170219223957p:plain

 ここでは、見える範囲と一度にスクロールする量を求めて変数にしています。

 

 テキストブロックの中身を変える

 UMGのテキストブロックには、内容を変更する方法が3つ(他にもあるかも)用意されています。

1.テキスト型の変数に直接バインドしてしまう方法Flashみたいな)

  その変数の内容を書き換えるだけで反映されます

2.関数にバインド(紐づけ)して、その関数の戻り値を使う方法

  その関数にパラメータ(引数)を渡していろいろ加工することができる

3.バインドせずに setText ノードを使う

  エンジンが値を見張ることがないので処理の負担が軽い

 

頻繁に値が変わる場合は、1か2が向いていますが、今回作ろうと思っているのは内容がほとんど書き換わらないので、3にします。

↓テキストをもらって書き換える関数です。

f:id:hiyokosabrey:20170218224228p:plain

 ForceLayoutPrepassノードと getDesireSizeノードのコンビネーションで新しいテキストブロックのサイズを取得します。右端の関数は、親のキャンバスパネルのサイズと比較してスクロールするかどうかをチェックする関数です。キャンバスパネルに収まらなかった場合のみスクロールできるようにしたいので比較してフラグを立てます。

f:id:hiyokosabrey:20170219223606p:plain

ついでにスクロールの限界位置を計算して変数に入れておきます。

 

フラグが立ったら

 フラグといってもブーリアン型の変数です。それをEventTick に Branchノードでつないでやります。スクロールが必要ない場合は処理を省けます。

スクロールが必要な場合は、キー入力を受けてスクロール処理をします。

f:id:hiyokosabrey:20170219225459p:plain

入力チェックのマクロはこんな感じ。

f:id:hiyokosabrey:20170218233113p:plain

Was Input Key Just Pressed ノードは、EventTickのように細かく処理が流れてくるところにつないで使います。Get Player Controller ノードがないと使えないので注意。

ゲームパッドとキーボードのカーソルキーを両方扱えるようにしたいので、OR(論理和)ノードで判定してます。

関数は出口が一つだけど、マクロだと分岐できるのでこういった場合とても便利です。

スクロールするために用意した関数は3つ。スクロール量を計算する関数2つと、実際に動かすための関数になります。

f:id:hiyokosabrey:20170219230322p:plain

f:id:hiyokosabrey:20170219230331p:plain

最終的に、青いノード(Vector2D)に移動後の値(目的地)が入るようにします。

キー入力のたびに上の関数が呼ばれ目的地が瞬時にセットされます。で、常時処理されるのがこの関数↓

f:id:hiyokosabrey:20170219230803p:plain

目的地から現在地の差分に0.1を掛けて現在地に加算したものを新しいポジションとしてセットします。これで常に目的地に向かって移動し続けます。0.1は速度の調整用として掛けています。

 

完成

f:id:hiyokosabrey:20170219231224p:plain

 試しに、シャーロックホームズの冒険(英語)から”ボヘミアの醜聞” の冒頭を流してみました。いい感じにスクロールできます。フォントは Canterburyという書体です。

f:id:hiyokosabrey:20170219231545p:plain

 無事ちゃんと動いていますが、まだ先があるのかわからないので、UIとしてはまだ完全ではないです。スクロールバーか、▼表示か、好みが分かれるところです。あと、上下の端に辿り着いたときに、ループさせるか否かも悩ましいところです。ということで今回はこの辺にしておきます。

ではでは

ステキなスクロールライフを

 

【おまけ】小数点でハマった

最初1行ずつスクロールしていたのですが、行数が多くなると誤差が出てきたり、端までいったときの判定が難しかったりで、結局 固定のスクロール量にしました。それほど悪くないと思います。同じ値を足し引きしてるはずなのに、数値が 0.0000008 みたいなことになるので、< >を使った判定が思うようにいかず頭をかかえることに・・・

 

【補足】うまくgetDesireSizeで取得できない場合

 まだ原因がよくわかっていないのですが、UMGの編集を開始してからしばらくはタイミングによってはまったくサイズが取得できなかったり、改行する前のサイズが取れてしまうようです(私の環境のせい?)。

 そこで確実に改行後のテキストブロックのサイズが取れる仕組みを見つけようといろいろ接続を試してみました。EventTickにつないでチェックすると間違いなく取れます。

f:id:hiyokosabrey:20170218215800p:plain

 DoOnceノードを使って処理をしたりしなかったりをスイッチングします。

 (このあたりいじってたら、いつのまにか、なくても取得できるようになってました・・・)

 

 

UMGでよくやらかすやつ

最近カレンダーを見るのが怖い。

年が明け、あっという間に1月も残り1週とちょっと。ブログの更新もペースが落ちて前回から随分間が開いてしまいました。世間から忘れ去られないように頑張っていきたいと気合だけは入れているのですが・・・

 

 さてさて、今でこそ注意するように習慣ができてきたのですが、UMGでアニメーションを作っていて、いざ見てみようと再生すると、「え?」という状況によくなります。最初は原因が分からないので、エンジンの不具合か?などと人のせいにしたりして、「UMGワケわかんな~い。」とか聞こえないのをいいことにぷつぷつとぼやいていたものです。

 原因が分かれば怖くないのですが、これが原因でUMGをキライになる人が増えるのは不幸なのでメモ程度に書いておこうと思った次第です。

 必ず起こるわけではないのですが、起こりやすいのが、フェードやフレームIN/OUTのように最初は見えない系。このタイプのWidgetを表示したときに、一瞬だけ変なタイミングのアニメーションが再生されることはないですか?その解決策をご紹介します。

 

 普通にWidgetブループリントを作って、UMGのタイムラインでアニメーションを作って完成したらコンパイルして保存すると思います。このとき必ず儀式というかお作法のようにやった方がいいのが、アニメーショントラックリストのフォーカス外しです。

 アニメーションを作って確認していると、アニメーショントラックリストがフォーカスした状態になっています。このフォーカスを外してから保存することがとても重要なのです。

f:id:hiyokosabrey:20170122211605p:plain

(外すとオレンジ色の帯が消える)f:id:hiyokosabrey:20170122211811p:plain

この地味な操作は、アニメーションが一切再生されていない状態、つまりUMGのデフォルト状態を確認するためです。このデフォルト状態の確認を怠ると、Add to Viewportしたタイミングで「!」となるのです。

  デフォルトの状態と、最初に再生するアニメーションの0フレーム目が同じ状態ならバッチリなのです。

 

 フレームインだと画面外、フェードインだと完全に透明、というのがデフォルト状態になるので、レイアウト作業がしづらいです。そこでポジションを動かしていたり、アルファの値を 0以上にしていたりするのですが、そのまま保存して確認、「!」というパターンからなかなか抜け出せない自分に若干イラっとすることに・・・

そこで『フォーカス外し』なのです。すこしの手間ですが、これを習慣づけることでストレスは減った気がします。この操作でシステム的に解決するわけではないので、期待された方がいたらゴメンなさい。確認は自分の目でします。

 

ではでは

今年もよろしくお願いします。

ステキなUMGライフを!