みつまめ杏仁

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

ちょっと変わった形のゲージをメッシュで作る《宿題編》

E3のトレーラーを見てて、ゲージの長さが可変していたのをみてしまったので、我流ですが対応してみました。

ここでいう可変とは、ゲージの物理的な見た目の長さのことです。成長段階やステータス変化を表現する方法の一つで、長さが比較しやすいゲージを使うタイプをよく見かけます。レイアウト的に余裕が無いとこの方法は使いにくいのですが、ゲージタイプのレイアウトを検討する際は、まず仕様として成長要素を反映するかどうかのコンセンサスを行ってからデザインを進めます。

 

 

まず可変するにあたって、検討したパターンは3つ。

 

①長さの違うゲージのメッシュを何個も用意する

 作るの大変そう。デザインの変更とか成長段階が変則でなければなんとかなるかも。

 

②メッシュそのものを計算でつくる

 動的生成(ロード中とか)とかだとプログラマさんに頼りたい。

 スタティックメッシュなら、MELとかPythonスクリプトで作ってもいいかも。

 

③同じ一つのメッシュで可変させる

 すでに作ったのがあるし、頂点シェーダーでなんとかできそう。

 

 

記事にしやすいという理由でに決定。は「よろしくお願いします!」か「オレガンバル!」かのどちらかになりそうなので。

 

③同じ一つのメッシュで可変させるということにしたので、すでに作ってあるやつを改造していきます。

 

全体の長さは前の記事で決めていますが、円周部分の5/4で作ったまま今回はいじらないようにします。

 

それなりに頂点数が多いのと、変な形をしているのですが、触りたい箇所は以下。

f:id:hiyokosabrey:20180616093311p:plain

ですが、

UVスクロールの増減速度を一定になるように一部のメッシュの形状を変えるのは、相当しんどいかと思われます。60fpsでアクションゲームとなると、UI表示で処理負荷が高くなるのは皆が幸せになれません。

なので、このゲージ本体は触らないことにします。

で、

出した結論が、「ゲージではなく後ろの枠を可変にする」です。

f:id:hiyokosabrey:20180616104130p:plain

 

この部分はUVを束ねてしまったとこなので、分離してやる必要があります。

f:id:hiyokosabrey:20180616114700p:plain

 

 というわけでBlender ゴー! (語感がいいので言いたいだけ)

f:id:hiyokosabrey:20180616111226p:plain

 

まず端っこの2頂点だけUVの頂点を移動させます。Gキーは押しながらではなく1回だけぽちっと押すだけです。そしてドラッグで移動したら左クリックで確定させます。

つづけて、

f:id:hiyokosabrey:20180616111854p:plain

 これでメッシュは編集完了。

FBXでエクスポートしてUE4Reimportします。

 

次に、テクスチャを改造します。

f:id:hiyokosabrey:20180616115447p:plain

これもUE4Reimportします。

 

見た目何も変わらなければ、BlenderでのUV編集は成功ということです。

f:id:hiyokosabrey:20180616115818p:plain

 

頂点を動かすためのマスクテクスチャを用意します。

f:id:hiyokosabrey:20180616120610p:plain

最小サイズ、4x4 pixelです。

これを圧縮ありで普通のカラーテクスチャとしてインポートします。

この場合はグレースケールにするより軽くなります。

 

この(頂点を)マスクするテクスチャをメッシュのUVポジションに重ねてみたイメージは下図のようになって、白い部分の頂点のみが可動対象になります。

f:id:hiyokosabrey:20180616134317p:plain

マテリアルを組んでみたのがこれ。

f:id:hiyokosabrey:20180616135039p:plain

長さは、Lengthという名前のScalarパラメータを仕込んでます。

マテリアルの改造は以上。

 

ConsructionScriptで、ゲージ同様にダイナミックマテリアルインスタンスを作って変数化しておきます。

f:id:hiyokosabrey:20180616140146p:plain

 

今回可変ゲージを扱うにあたり、仕様を変更することにします。

レベルBPから、ゲージの長さを 0.0~1.0 の値で受け取っていたのを、2000とか直接の数値で受け取るように変更。

 

そこで

受け取った値を割合に変換するマクロを用意します。getVitalRatioと命名。

f:id:hiyokosabrey:20180616232329p:plain

 Inverse Lerpノードを使うと、渡した値がどの辺にいるか、割合で返してくれます。

 

追記

この Inverse Lerp は Ver 4.19 から バグフィックスされて Normalize to Range に生まれ変わりました。

f:id:hiyokosabrey:20180712003932p:plain

 

次に

前回 Event BegnPlay につないでいた関数 initGauge をグラフから消します。

f:id:hiyokosabrey:20180616231657p:plain

そしてこの initGauge関数を編集します。

 外から呼び出してもらう形にします。

f:id:hiyokosabrey:20180616233114p:plain

初期化のタイミングはゲージの表示開始時か、ゲージの長さが変化したときになると思われるので、この関数内で枠の長さを変更するパラメータ Length に値を入れて枠の長さを確定させます。ここは仕様によりますが、いったんゲージ本体も満タンになるようにもらった値に合わせて長さを変えています。

 

枠の長さを変えるために、Length に入れる値として、 constFrameLengthというFloat型の変数を用意しています。

f:id:hiyokosabrey:20180617093625p:plain

定数(変化しない値)として扱うので、初期値(Default Value)をあらかじめセットしてあります。どんな値かというと・・・

 

枠のメッシュは、0 で一番長い状態です。右方向(X軸でプラス)に移動するようにマテリアルを組んでいるので、Length には正の数値が入ります。

実際のメッシュのサイズも関係してますが、直線部分をBlenderで引き延ばすときに計算した値がここで役立ちます。

f:id:hiyokosabrey:20180607234547p:plain

UE4で100倍スケールでインポートしていたのを思い出したので、

100倍して -1199.94。

右に動かすので マイナスの符号を消す感じで、パラメータにすると 1199.94。

f:id:hiyokosabrey:20180617085122p:plain

Float型なので入力すると勝手に若干のブレが出ますが、このまま進めてみます。(画面で確認して気になるようだったら改善を考えよう。)

 

ここまででプレビューしてみたいので、レベルブループリントも編集します。

f:id:hiyokosabrey:20180617093416p:plain

 

f:id:hiyokosabrey:20180616150248j:plain

いい感じです。

表示部分はなんとかできました。

レベルブループリントの 変数 PlayerVital の値を変えてみると、ゲージと枠がちゃんと連動しているのが分かります。

f:id:hiyokosabrey:20180617100413j:plain

 

 

あとは、受け取る値が変わったので、ゲージの減る動きを調整します。

f:id:hiyokosabrey:20180617100735p:plain

NewVital からは 0.5 とかではなく 1250 のような値になったので、マクロを介してマテリアルに値を渡します。

f:id:hiyokosabrey:20180617101421p:plain

ゲージのブループリントはこれでOKです。

 

テスト用にレベルブループリントも少し改造します。

f:id:hiyokosabrey:20180617101717p:plain

 乱数が0.01 ~ 0.1 だったのを 変えているだけです。

テスト用なのでここは好みで。

 

Vitalの 初期設定を 2000 にして試してみます。

f:id:hiyokosabrey:20180617102430g:plain

 

なんとかできた感じです。

 

Twitterで「ゲージの長さ対応は、またそのうち・・・」とつぶやいて宿題にしていたのですが、思っていたより記事の反響があったので、勢いつけてやってみました。

 

「ゲームの数だけゲージがある。ゲージの数だけ仕様がある。」

 

ではでは

まだ見ぬゲージを求めて

ステキなゲージライフを!

 

 

 

 

ちょっと変わった形のゲージをメッシュで作る《おまけ編》

やっぱり下敷きとか枠が無いと完成した感じがしないので作ってみます。

 とその前に、前回の記事で満タンを 1.0 に、空っぽを 0.0 という仕様にしていたので、見た目にゲージが見えないのに、まだ「ある」状態が起こる仕様になっていました。いわゆる「表示バグ」というやつで、プログラマにとって迷惑極まりないやつです。

 修正方法は以下。

f:id:hiyokosabrey:20180610165946p:plain

 テクスチャの端から端までスクロールさせない場合はLerpノードが便利。

f:id:hiyokosabrey:20180610195911p:plain

Lerpノードを使うと受け取る値の範囲は0~1で変わらないので、プログラマに気づかれる前に直せればセーフ!プログラムの修正は不要!

 

Lerpノードの Bのピンにつながっているのは、0.99609375 という値です。(丸められてすべての桁が表示されていません)どこから来た数字かといえば、テクスチャの中のゲージ自身の長さが 510px で、移動量も510px動くと見えなくなるからで、

f:id:hiyokosabrey:20180610194904p:plain

(ちょっと見にくいですが上図の赤い枠がUV頂点の範囲です。)

510をテクスチャのサイズで割るので、 510 ÷ 512 = 0.99609375 というわけです。

なぜ 510 かは、前々回の記事にて書いています。

 

ちなみに、ゲージの長さが 510pxでテクスチャサイズが 1024pxだったりすると、

512 ÷ 1024 になるので、 スクロール範囲は 0.0 ~ 0.498046875 になります。

 

0.0 で満タン、 0.99609375 で消える

これを Lerpノードにセットして、Alapha ピンに入ってくる 0.0 ~ 1.0 によって線形補間の結果が出てくるという訳です。

 

 

 表示バグも直ったので、

まずは簡単な下敷きとして、テクスチャを2枚使う方法を紹介しておきます。

こちらの方が解像度に対してエッジのアルファを調整しやすいのとゲージが無い部分も表示されるのでオススメなんですが、下敷きと合わせたり別のゲージを重ねるのは難しくなります。 

f:id:hiyokosabrey:20180610162441p:plain  ← 8x32pxのグレースケールテクスチャを用意。

Tiling Method は Wrap です。

 

マテリアルの Opacity ピンにつなぐだけです。

f:id:hiyokosabrey:20180610163618p:plain

このようになります。

f:id:hiyokosabrey:20180610163753j:plain

 

背景に来る色によっては見えにくくなるので、やっぱり枠はあった方がいいよねってことで、 ゲージの下敷きと兼用で外側に枠をつけます。 

今回は ゲージのメッシュからフチドリを生成します。

ではさっそく Blender  ゴー!

 

まずゲージのメッシュを複製します。

そして ぐるっと辺を選択したら、

f:id:hiyokosabrey:20180610224012p:plain

選択 > 辺ループ を使うと楽です。あとはShiftキーを押しながら右クリックで追加選択できます。

1周選択できたら「個々で押し出し」します。

f:id:hiyokosabrey:20180610223319p:plain

カメラを斜めから見下ろす感じにしてから、実行すると押し出す方向がよく見えます。押し出し中(指を離すまでの間)に Ctrl キーを押すと押し出す方向をある程度拘束できるのでまっすぐ下に伸ばしやすくなるのですが、見る角度によっては斜めになってたりします。

そこでおすすめの方法がこれ。

押し出し実行直後、勝手にマウスドラッグに追随するので、いったん右クリックで切り離します(移動が無かったことになるだけ)、そのままビューの中の青矢印(Z軸)をドラッグするとまっすぐ移動ができます。

(この辺の不思議オペレーションがBlenderから人を遠ざけている気がする・・・)

 

いくらか押し出したら、エッジの選択は解除しないままで、ビューを戻します。 テンキーの[7]と[5]で「トップ・平行投影」にします。

そして、トランスフォームの中にある、収縮/膨張を実行します。

f:id:hiyokosabrey:20180610210626p:plain

f:id:hiyokosabrey:20180610223529p:plain

最初は少し歪んでいるので、ツールのオプション設定にある均一オフセットのチェックを付けて有効にすると上図のようになります。

f:id:hiyokosabrey:20180610211157p:plain

この操作は平面ポリゴンの外側にベベルを付けたいときに使えます。

オフセットの値をフチドリの幅に合うように調整します。

 

オブジェクトモードに切り替えて、

f:id:hiyokosabrey:20180610211844p:plain

Z軸スケールを0にしてつぶします。

f:id:hiyokosabrey:20180610211951p:plain

ぺちゃんこですが法線を維持しているので不思議な見た目です。

オブジェクト > 適用 > 拡大縮小

で形状はそのままに スケールを 1.0に戻します。

f:id:hiyokosabrey:20180610212141p:plain

 

 メッシュの状態はこのようなってます。

f:id:hiyokosabrey:20180610224206p:plain

 これに貼るテクスチャを用意します。

f:id:hiyokosabrey:20180610230620p:plain ← 32x32px

これをBlenderに持って行っていきます。

新しくマテリアルとテクスチャを作ってセットしたらUV編集するのですが、フチドリの部分のUV頂点が重なっているので、まずこれをほぐします。

 

レイアウトをUVEditingに切り替えたら、

右側のビューで、Ctrlキー押しながら左ドラッグで頂点をいくつかまとめて選択しつつ、左側のビューで[W]キーを押して 「溶接」 を選択します。

f:id:hiyokosabrey:20180610231844j:plain

f:id:hiyokosabrey:20180610232001p:plain

すると UVの頂点が1か所に束ねられるので、今度は[G]キーを押して移動させます。ちなみに選択解除は[A]キーでできます。

これを繰り返してざっくりとまとめます。

f:id:hiyokosabrey:20180610233043j:plain

 ゲージの端を整えるために辺を増やします。

「ナイフ」ツールを使います。

f:id:hiyokosabrey:20180610234347g:plain

一つ目は既存の頂点をクリックして、あとは適当にメッシュの外でクリックしたら、[Enter]キーで確定。

まっすぐにしたいので、最初に選んだ頂点とX軸の値をコピペで合わせます。

f:id:hiyokosabrey:20180610234937p:plain

ちょっと面倒だけど、テクスチャのサイスがとても小さく済むので頑張ります。

f:id:hiyokosabrey:20180610234828p:plain

切ると言っても、頂点と辺を増やしているだけです。

f:id:hiyokosabrey:20180610235358p:plain

もう一方の端も同様に処理したいのですが、辺が斜めなので、コピペが使えません。

ナイフツールで2か所目のクリックでなるべく水平になるようにします。

f:id:hiyokosabrey:20180610235643p:plain

たまたま、X軸のラインがあるので分かりやすいです。

 

再びUV編集です。

頂点が増えているので、また束ねます。

f:id:hiyokosabrey:20180611000022p:plain

最終的にこうします。

f:id:hiyokosabrey:20180616114318p:plain

さらに反対側の端のUVも

f:id:hiyokosabrey:20180616114400p:plain

重ねて

f:id:hiyokosabrey:20180616114258p:plain

出来上がり。

 

さっそくUE4に持っていきます。

テクスチャもインポートして、マテリアルを作ったらメッシュにセットします。

f:id:hiyokosabrey:20180611002149j:plain

問題なさそうなので、前回のブループリントに追加します。

f:id:hiyokosabrey:20180611003358p:plain

同じようにスタティックメッシュコンポーネントを追加して、Detailsタブから用意したメッシュをセットします。

f:id:hiyokosabrey:20180611003701j:plain

おっと、表示順がおかしいので、設定を変更します。

半透明のオブジェクトは専用の優先順位で管理します。

Detailsタブから sort で検索します。

f:id:hiyokosabrey:20180611004006p:plain

Translucency Sort Priority は数値の大きい方が後に描かれます。また体力のような常に手前に描かれるものは、エフェクトなどの半透明に負けないように大きな値を入れます。シーン内で干渉し合わないように注意が必要です。

f:id:hiyokosabrey:20180611004430j:plain

いい感じになりました。

 

一応完成ですがせっかくなんで、もう少し遊んでみます。

 

テクスチャを改造します。

f:id:hiyokosabrey:20180608214046p:plain

これをグレースケールにしてサイズもタテ方向だけ小さくします。

f:id:hiyokosabrey:20180611234609p:plain

512x8 です。(↑白い部分がこのページの背景に溶けるので枠線を付けてます)

右端はそのまま 2px の黒い部分があります。アルファチャンネルは無しのグレイスケールです。

 

これとカラーのテクスチャ。

f:id:hiyokosabrey:20180611234900p:plain ← 16x32 (実寸)

これもアルファチャンネルは無しです。

あとは、先の説明で使ったアルファ用のテクスチャ。

f:id:hiyokosabrey:20180611235226p:plain  ← 8x32 (実寸)

(↑白い部分がこのページの背景に溶けるので枠線を付けてます)

テクスチャは以上。

これをインポートしてマテリアルに持っていきます。

 

f:id:hiyokosabrey:20180612000320p:plain

TexCoordinate ノードが2つありますが、上の方は設定値を変更しています。

f:id:hiyokosabrey:20180612000541p:plain

左上の Static Switch Parameter ノードはこのままだと固定された状態(初期値一択)ですが、マテリアルインスタンスにすると、値を変更することができます。

f:id:hiyokosabrey:20180612001141p:plain

名前に Static が付いている通り、動的に変化させることはできません。

このマテリアルの初期状態は緑色になるように値をつないでおきます。

マテリアルができたのでマテリアルインスタンスを作ります。

コンテンツブラウザからこのマテリアルのアイコンで右クリックすると一番上にある Create Material Instance を選択。

f:id:hiyokosabrey:20180612002250p:plain

ダブルクリックすると、パラメータが触れるようになってます。

f:id:hiyokosabrey:20180612002429p:plain

 

マテリアルは一式揃ったので、ゲージのブループリントにゲージのスタティックメッシュコンポーネントをもう一個追加します。

f:id:hiyokosabrey:20180612002754p:plain

ゲージのメッシュと、できたばかりのマテリアルインスタンスをセットします。

全部同じ位置で重なってるので、Translucency Sort Priority で表示優先を調整します。

↓重なり順のイメージ。

f:id:hiyokosabrey:20180612003150p:plain

メッシュがセットできたら、

Construction Script で、赤いゲージ用の ダイナミックマテリアルインスタンス MID_Damage を準備しておきます。

f:id:hiyokosabrey:20180612003653p:plain

 

新しくゲージを初期化する関数を用意します。

f:id:hiyokosabrey:20180612003856p:plain

この関数を、Event Begin Play につなぎます。

f:id:hiyokosabrey:20180612004044p:plain

満タンでスタートしたいので 1.0 を引数として与えています。

 

Event Tick につないでいた部分を改造します。

f:id:hiyokosabrey:20180612004632p:plain

ScalarParameterValueノードにつないでいた MID_Vital は MID_Damageに入れ替えています。

 

値を受け取っていたイベントも改造します。

f:id:hiyokosabrey:20180612005035p:plain

ゲージのブループリントはこれで完成です。

 

レベルブループリントも改造します。

f:id:hiyokosabrey:20180612005304p:plain

スペースキーを押すたびに、0.01~0.1 の範囲のランダムな値でゲージを減らしていくようにしました。

 

では再生してみます。

f:id:hiyokosabrey:20180612010026g:plain

よしよし。

メッシュの頂点数は結構使ってるので、テクスチャはものすごく節約しました。

 

一応 Inverse Lerpノードを説明しておきます。

f:id:hiyokosabrey:20180612010926p:plain

 これは Lerp とは逆に作用するノードで、「今どのへん?」というのを割合で返してくれます。

上の場合0~2500 の中で、 2200はどの辺に位置しているのか、が分かります。

 

上限や下限が変動するような場合などに特に効果を発揮します。

 

オマケなのになかなかのボリュームになってしまいましたけど、いかがだったでしょうか?

テクスチャの節約ができるので、テクスチャ容量が厳しいときは、メッシュで作れるといいのですが、UMGのようにポストプロセスから切り離した描画が難しいので、カラーの調整が悩ましいところです。

 

今回はこの辺で

ではでは

ステキなゲージライフを!

 

 

 

 

ちょっと変わった形のゲージをメッシュで作る《後編》

前回の続き。

f:id:hiyokosabrey:20180608002318p:plain

カーブを描いたゲージを作る場合、できるだけ細かいメッシュで作らないと、テクスチャが歪みます。細かいメッシュは頂点数が多くなるのでUV編集が地獄です。キレイに比率を維持してまっすぐなUV展開をしてくれるスクリプトでも書ければいいのですが、労力の割に使用する機会がが少なそうなのもあって、今までほとんど力業で作ってきました。

今回 Blenderのモディファイア『細分割曲面』を使ってみるとローポリからいい感じのカーブができたので作業時間が大幅に短縮できました。Mayaが手元にないので説明できないですが、Mayaでも同様の操作ができるのは確認しています。

 

さてさて

完成したメッシュにテクスチャが貼れたのでFBXの形式でエクスポートします。

FBXのエクスポートについては、過去記事を貼っておきます。 

limesode.hatenablog.com

UE4でインポートしてみました。

f:id:hiyokosabrey:20180608194123j:plain

無事エクスポートできたようなので、Blenderを落として今度はテクスチャを仕上げます。

f:id:hiyokosabrey:20180606225153p:plain

Blenderに持っていったテクスチャを本番用にします。

f:id:hiyokosabrey:20180608214046p:plain

アルファチャンネルは、上下に黒とグレーを1ピクセルずつ。

f:id:hiyokosabrey:20180608214140p:plain

右端の部分を拡大するとこんな感じ。

f:id:hiyokosabrey:20180608214338p:plain

これはポリゴンのエッジをマイルドにする効果があります。

f:id:hiyokosabrey:20180608214758j:plain

このアルファチャンネルを使った余白がないとポリゴンのエッジがクッキリでます。

f:id:hiyokosabrey:20180608215144j:plain

拡大している状態だと目立たないですが、解像度が低かったり、頂点数が少ないとエッジのクオリティが悪目立ちすることがあります。

テクスチャにアルファチャンネルが使えない場合は頂点カラーでアルファを仕込むこともあります。Blenderは頂点カラーにアルファ使えないのでちょっと工夫が必要です。

 

さてさて

テクスチャーのインポート設定ですが、デフォルトのままだとうまくいかないので変更します。

f:id:hiyokosabrey:20180608232553p:plain

ピクセルが荒れてほしくないのでリッチな User Interface2D を選択。

UIでミップマップは不要なので、 No MipMaps

 

今回テクスチャを目いっぱい使ってて、UVスクロールする範囲がテクスチャの外まではみ出しているので、タイリングメソッドを Clamp にしておく必要があります。

 

 

テクスチャをインポートできたら、マテリアルを作っていきます。

コンテンツブラウザのテクスチャアセットのアイコンの上で、右クリックしてCreate Material するとラクチンです。出来立てホヤホヤはこんな状態。

f:id:hiyokosabrey:20180608225408p:plain

UI用に設定を変更します。

f:id:hiyokosabrey:20180608230116p:plain

半透明を使用するので、Blend Mode を Translucent に、

光源計算しないので、 Shading Model を Unlit にします。

あと、忘れがちなのが、Apply Fogging。

f:id:hiyokosabrey:20180608230239p:plain

フォグもいらないので外します。

 

設定が変わると、マテリアルのピン構成が変化するのでつなぎ直します。

f:id:hiyokosabrey:20180608230534p:plain

この状態でメッシュにセットしてみます。

先にインポートしてあったメッシュのエディタを開いてセットします。

f:id:hiyokosabrey:20180608231425j:plain

こんな感じになりました。

f:id:hiyokosabrey:20180608231704j:plain

これをゲージらしく増減できるようにします。

マテリアルを以下のように組みます。

f:id:hiyokosabrey:20180608232012p:plain

左端のノードが、Scalar Parameter Value ノードです。ブループリントから値を受け取ることができます。

OneMinus(1-x)ノードで値を反転しています。これは、0 の時にゲージが満タンで、1.0 の時に空っぽになるのを逆にするためです。

AppendノードのAとBは、それぞれ UとV で、Uが水平方向、Vが垂直方向です。

 

では、ブループリントを作ります。

f:id:hiyokosabrey:20180608233932p:plain

まずは、メッシュをコンポーネントとして追加します。

緑の Add Component ボタンを押して、Static Mesh を選択します。

f:id:hiyokosabrey:20180608234215p:plain

そのままだと空っぽなので、

Detailsタブから、作ったメッシュをセットします。

f:id:hiyokosabrey:20180609074235p:plain

マテリアルをここで付けることもできます。

今回は Dynamic  Material Instance にするので、マテリアルの有無は無視できます。

 

グラフのタブを Constuction Script に切り替えて、以下のようにつなぎます。

f:id:hiyokosabrey:20180609075340p:plain

上図は Dynamic化するマテリアルを直接セットしてますが、すでにメッシュにマテリアルがセットされている場合はGet Material ノードを使うこともできます。

 

ちなみに Dynamic Material Instance の語順が気になるところですが、公式のドキュメントには括弧書きで MID としているので、右端の変数名 は MIDで始めてます。

以下キャプチャして抜粋。

f:id:hiyokosabrey:20180609080345p:plain

Instanced Materials | Unreal Engine

 

グラフのタブを EventGraph にして、新しく Float型の変数を2つ用意します。

一つはカスタムイベントにつないで、外から受け取るようにします。

f:id:hiyokosabrey:20180609082533p:plain

このブループリントでは「UI表示」が主な仕事としているので、ゲージの長さを計算するようなものはありません。値を受け取って素直に表示するだけにします。

ひとまず受け取る値は 0.0 ~ 1.0 を想定。1.0=100%で満タンという仕様です。

 

ゲーム開発ではゲームバランスの調整が理由で体力の上限はよく変動します。成長要素があればプレイ中に変動します。なので、そのあたりはゲームシステムの方でプログラマに集約、管理してもらうのが無難です。

 

で、受け取った値をゲージに反映する部分はこうなります。

f:id:hiyokosabrey:20180609083815p:plain

素直に反映するだけだと面白くないので動きを入れてます。簡単なイージングです。

 

処理負荷的に渋い顔されたら、さっきのカスタムイベントでこうすればOKです。

f:id:hiyokosabrey:20180609084033p:plain

 

ブループリントは完成です。

ワールドで確認します。簡単な方法は ゲージのBPをワールドにドロップして直接置いてしまう方法です。UIなので実際には誰かに Spawn してもらう方法になるかと思います。

今回は直接置きました。

f:id:hiyokosabrey:20180609084814j:plain

 

レベルブループリントを開いて編集します。エディタのBlueprintsボタンから選択。

f:id:hiyokosabrey:20180609085149j:plain

 

ワールドアウトライナからゲージのBPをドラッグ&ドロップします。

f:id:hiyokosabrey:20180609085421p:plain

 

この青いピンからドラッグして、中のカスタムイベントを探します。

f:id:hiyokosabrey:20180609085715p:plain

検索フォームで、call ってすると、関数とイベントを候補として絞り込むことができます。実はエンジンの言語設定を英語にしている最大の理由がこれです。検索キーワードを1個覚えるだけです。

日本語環境だとこれができないので結構ストレスに感じるのは私だけ?

f:id:hiyokosabrey:20180609090446p:plain

f:id:hiyokosabrey:20180609090921p:plain

ショートカットキーも使うからいちいち入力モード切り替えるの面倒だし・・・

 

で、関数を取り出してつないだら、Input ノードをつなぎます。

f:id:hiyokosabrey:20180609090906p:plain

Random Float in Range ノードは処理が走るたびに、指定した範囲で乱数を発生させてくれます。

 

コンパイルして、再生してみましょう。

f:id:hiyokosabrey:20180609091425j:plain

しーん・・・

カメラに映るように調整したはずなのに・・・。

実はこれ変数の初期値が 0.0 になっているからです。

ゲージが満タンから開始するには、変数に初期値を入れておきます。

いろんな入れ方があるのですが今回は、レベルBPの方で入れることにします。

f:id:hiyokosabrey:20180609091847p:plain

再生してみると、

f:id:hiyokosabrey:20180609091959j:plain

ちゃんと出てきました。

スペースキーを叩いてみましょう。

f:id:hiyokosabrey:20180609092605g:plain

うまくいったようです。

30fpsでGIF化したのでちょっとぎこちないけど、実際はもう少し滑らかに動きます。

 

以上で完成、といっても毎度のことながら、モックアップ的な作りですみません。

《後編》はここまでにしようと思いますが、このままだとちょっと物足りないので、次回《おまけ編》を書こうと思います。

 

ではでは

ステキなゲージライフを!

 

ちょっと変わった形のゲージをメッシュで作る《前編》

キングダムハーツIIIのトレーラーを見てて急に作ってみたくなったのでメモメモ。

 3/4の円形部分と直線部分が合わさったゲージで、スクショから割り出した直線部分の長さは円周のおよそ1/2。全部で円周の5/4な長さっぽいです。

f:id:hiyokosabrey:20180605223758p:plain

UVスクロールを使うのでこの辺りをアバウトに設計するとゲージの増減速度が不自然になるので慎重に進めます。円形部分のUV編集をエコに作りたいので、円周の5/4に決めます。

 

メッシュはBlenderで作っていきます。

まだまだ操作に詳しくないので手探り状態ですが、なるべく細かく手順を書くようにします。

 

まずは作業するビューをテンキーの[7]と[5]を押してトップ・平行投影に切り替えます。

f:id:hiyokosabrey:20180605224321p:plain

円柱を生成します。設定値は以下。

f:id:hiyokosabrey:20180605225331p:plain

半径は計算しやすいように 5 にしています。今は大きさではなく頂点の形状が重要なのでいったんサイズのことは忘れても大丈夫。

 

モードを 編集モードに切り替えます。

f:id:hiyokosabrey:20180605231612p:plain

手前(Z軸プラス側)のフタだけが欲しいので、オブジェクトを回しながら、フタ以外の他のメッシュを選択して削除(Deleteキー)します。

f:id:hiyokosabrey:20180605230450g:plain

フタだけになったら、オブジェクトモードに戻します。

f:id:hiyokosabrey:20180605231732p:plain

円柱から作り始めて少し浮いている状態なので、スケールでつぶします。

f:id:hiyokosabrey:20180605231227g:plain

拡大縮小のZ軸に 0 を入力するとペシャンコになります。

続けて、このつぶれた状態を適用してスケールを 1倍に戻します。

オブジェクトモード左のオブジェクトメニューをクリックして、

適用 > 拡大縮小 を選択。

f:id:hiyokosabrey:20180605232322p:plain

これをやっておかないと、画面に表示する際に扱いにくくなります。

 

次に中を抜きます。

編集モードに切り替えます。

f:id:hiyokosabrey:20180605231612p:plain

まず放射状のエッジを8本選んでおいて、 ツールにある 「細分化」 を掛けます。

f:id:hiyokosabrey:20180605233538g:plain

 

細分化で分割できたら、中央のメッシュを削除して穴の大きさを調整します。

f:id:hiyokosabrey:20180605234901p:plain

 

このへんでテクスチャを用意します。

f:id:hiyokosabrey:20180606230752p:plain

サイズは 512x32 、UVを当てやすくするために 51x32で色分けします。

右端に 2px 余りが出ます。

 

Blenderに戻ってマテリアルをセットします。

編集モードでメッシュを全て選択した状態で、マテリアル設定に切り替えて、新規マテリアルを作ります。

f:id:hiyokosabrey:20180606224659p:plain

シェーディング設定にある陰影無しにチェックを付けると作業しやすくなります。

f:id:hiyokosabrey:20180606225053p:plain

次にテクスチャをセットします。

f:id:hiyokosabrey:20180606225614p:plain

新規ボタンを押したら、用意しておいたテクスチャをセットします。

f:id:hiyokosabrey:20180606225818p:plain

 

テクスチャをセットできたら UVを編集します。

 まずエディタのレイアウトを UVEditing に切り替えます。

f:id:hiyokosabrey:20180606230032p:plain

最初は適当なテクスチャが当たっているので、今回用意したテクスチャをセットします。

f:id:hiyokosabrey:20180606231416p:plain

すると以下のようになります。

f:id:hiyokosabrey:20180606231532p:plain

メッシュのワイヤーが表示されていない場合は、右側のビューからメッシュを選択すると表示されるようになります。

 

UVを動かす際に、UV編集対象のメッシュを選択しながら編集を進めるのですが、以下のスイッチを変えると、メッシュの選択方法が変わります。

f:id:hiyokosabrey:20180606232923p:plain

まずは上段のスイッチで進めます。

Blenderの初期設定では、UVEditingレイアウトにすると2分割されます。

右のビューで編集対象のメッシュを選択状態にします。

f:id:hiyokosabrey:20180606235540p:plain

すると、下のようになるので、

f:id:hiyokosabrey:20180606235637p:plain

まっすぐにします。UVメニューにある ピクセルに吸着 を使うと正確です。

f:id:hiyokosabrey:20180606235735p:plain

メッシュとUVの位置関係はこんな感じ。

f:id:hiyokosabrey:20180607000401p:plain

ここでモディファイアを使います。

エディタのレイアウトを Default に戻します。

モディファイア設定に切り替えて、下のプルダウンリストをクリックします。

f:id:hiyokosabrey:20180607224514p:plain

細分割曲面 を選択。

f:id:hiyokosabrey:20180607224913p:plain

詳細設定ができるようになるので、ビュー の値を 3 にします。

f:id:hiyokosabrey:20180607225317p:plain

 カーブしたゲージはなるべく細かい方がテクスチャの歪みが少なくなります。

f:id:hiyokosabrey:20180607225515p:plain

一旦オブジェクトモードにして、「適用」します。

f:id:hiyokosabrey:20180607225924p:plain

編集モードにして左下 1/4 のメッシュを削除します。

選択が残っていれば、選択メニューから 反転 を選ぶとラクです。

f:id:hiyokosabrey:20180607230258p:plain

かなり細かいので、いくつかのエッジを溶かします。

 

f:id:hiyokosabrey:20180607230527p:plain

辺をひとつ選んで、選択メニューから 辺ループ を選択。

f:id:hiyokosabrey:20180607230736p:plain

続けて、Deleleキーを押したらコンテキストメニューがポップするので、辺を溶解 を選択します。

f:id:hiyokosabrey:20180607231106p:plain

最終的にこうなりました。

f:id:hiyokosabrey:20180607231723p:plain

直線部分を作るので、延ばす部分の辺を選択します。

f:id:hiyokosabrey:20180607232033p:plain

ツールメニューから、個々に押し出し を選択。

クリックした瞬間に、マウスカーソルにくっついてくるので・・・

f:id:hiyokosabrey:20180607232608p:plain

慌てずに、Ctrl キーを押して移動方向を水平にしたら指を離します。

f:id:hiyokosabrey:20180607232953p:plain

長さを求めるために、再び辺を選択します。

f:id:hiyokosabrey:20180607233600p:plain

辺の中点の座標を確認します。中点は上の図だと 緑と赤の矢印の交点です。

f:id:hiyokosabrey:20180607233817p:plain

この値を半径とします。円周の長さは 2πR なので、

半径 × 2 × 3.14159  になります。

その半分ということでさらに 2で割ると直線部分の長さが判明します。

直線部分の先端の辺を選択して、長さを入力します。

f:id:hiyokosabrey:20180607234547p:plain

f:id:hiyokosabrey:20180607234401p:plain

メッシュは完成です。あとは直線部分のUVを編集します。

ぺしゃんこになってるので広げます。

f:id:hiyokosabrey:20180607234832p:plain

マウスの右ボタンでドラッグすると頂点を1つずつ移動できます。

(ちょっとだけ右ボタンドラッグすると、指を離してもマウスについてきます。これややこしい。)

四角く広げたら面のつながりがおかしくなってないか確認します。

f:id:hiyokosabrey:20180607235906p:plain

選択タイプを変えると確認がラクです。

f:id:hiyokosabrey:20180608000232p:plain

一見うまくつながっているように見えますが、一か所だけ 頂点 を選択すると・・・

f:id:hiyokosabrey:20180608001006p:plain

この場合は、直線部分のメッシュを選んだ状態で、メッシュメニューの 面 > UVの反転 を選ぶと解決します。

で、いい感じなのがこれ。

f:id:hiyokosabrey:20180608001709p:plain

 

モデルを確認します。エディタのレイアウトを Defaultに戻します。

f:id:hiyokosabrey:20180608002135p:plain

ビューを テクスチャー に切り替えてみると・・・

f:id:hiyokosabrey:20180608002318p:plain

いい感じにUVが当たっています。

これで完成です。あとは FBXで書き出すだけです。

 

さすがに長くなってきたので、続きは後編で。

UE4に持って行って、マテリアルを作って、テクスチャを整えて、ブループリントからいじれるようにします。

 

ではでは

ステキなゲージライフを!

 

 

 

UE4のフォントで足りない文字を補充する

文字が足りなくて困ったことはありませんか?私はあります。

アンリアルエンジンではフォントをアセット化して、適時ラスタライズして画面に表示してくれますが、グリフ(字形)がそのフォントに含まれていないと無いとブランク文字が表示されます。

ゲーム開発で必ずと言っていいほど見かける以下の記号。

 

f:id:hiyokosabrey:20180522014222p:plain

 

 これらが入っていないフォントがまだ多くあります。特に作られた年度が古いフォントは入っていない率高いです。(ユーロの記号もそうですね)。権利表記で使われる記号なので、出さないわけにはいきませんし、(C)とか(R)のように括弧書きもOKなんですが、ちょっとカッコ悪いですよね。

 UE4ではフォントのグリフが足りない場合にサブフォントを登録して解決することができます。ところがフォントごとにデザインやパラメータが違うので、文字を並べたときに高さが揃わなかったりしてうまく並ばないことが多いのです。

 なので、たかが3文字程度作ってしまえ~、ということで今回フォントを作るところから書いていきます。といってもUE4に持っていく流れ程度ですけども。

  

 さて、フォント作成ツールを探してみて、なじみの武蔵システムさんのOTEdit を使おうと思ったのですが、気軽にオススメできる値段じゃないので、今回はFontForge というフリーのアウトラインフォント作成ツールを使ってみることにしました。

 

f:id:hiyokosabrey:20180522231610p:plain

公式には日本語版が見当たらないので、日本語版のセットアップ方法についてはこちらの記事を参考にしました。

この夏はフリーソフトでフォント作成に挑戦してみよう:ちはやろぐ.aep - ブロマガ

基本的な使い方については、上の記事にだいたい載ってるので省略します。

 

起動して「新規」を選択すると下のようなウィンドウが開きます。これがメインのウィンドウです。

f:id:hiyokosabrey:20180522232413p:plain

このウィンドウを閉じると終了してしまうのでご注意を。

四角の中にグレーのバッテンが書かれているのがグリフが無い状態。上の小さな文字がサンプルの文字です。(C)と(R)はすぐに見つけられるので、ダブルクリックしてグリフを作っていきます。↓グリフエディタはこんな感じ。

f:id:hiyokosabrey:20180522233813p:plain

外側の輪っかはコピぺできるので、(R)の方は少しラクができました。

f:id:hiyokosabrey:20180522235732p:plain

 

さて、ここまできて TM が作れないことが判明します。

デフォルトのエンコーディングが  ISO 8859-1 になっていて 255文字分しかエディットできないのです。そこでエンコーディングを変えます。

メニューから

エンコーディングエンコーディング変換  と進むとリストが出てくるので、

ISO 10646-1 を選択します。

f:id:hiyokosabrey:20180522235104p:plain

これで、メインのウィンドウから U+2122 のところまでスクロールすることができるようになります。

f:id:hiyokosabrey:20180522235625p:plain

とりあえず3つ作ることができたので、フォント情報を設定します。

メニューから、 エレメント > フォント情報 を選択します。

設定用のウィンドウに、フォント名や著作者情報を入力していきます。

f:id:hiyokosabrey:20180523001315p:plain

AddSymbと名付けてみたけど、なんか関数名みたいw

 

ちなみに文字ごとの幅を設定するのは、メニューから メトリック を選択すると設定可能です。

いったん作業データを保存します。拡張子が sfd になります。

次回に引き続き編集する際はこの SFD形式のファイルを開けば継続できます。

 

で、いざフォント書き出しです。

ファイル > フォントを出力 を選択するとウィンドウがポップアップします。

f:id:hiyokosabrey:20180523002901p:plain

OpenTypeを選択して、生成ボタンをクリックします。

下のようなダイアログがポップアップしますが、気にせず生成ボタンをクリックします。

f:id:hiyokosabrey:20180523003129p:plain

 

うまく書き出せたらフォント完成です。

f:id:hiyokosabrey:20180523003333p:plain

このフォントをUE4に持っていきます。

 

フォントのインポート方法は公式サイトが丁寧で詳しいので、今回は説明は省きます。

Unreal Engine | フォントのインポート

 

 まずメインのフォントをアセットにします。

まずサブフォント無しの状態。

f:id:hiyokosabrey:20180525014008p:plain

 UMGのキャンバスにTextBlockを置いてみます。

表示内容は以下。ちょっと文字が小さくに見にくいですが

f:id:hiyokosabrey:20180525014048p:plain

でキャンバスはというと

結果はこうなりました。

f:id:hiyokosabrey:20180525014135p:plain

見事にグリフが足りてないですね。

そこで、サブフォントにFontForgeで作ったフォントをセットします。

f:id:hiyokosabrey:20180525014915p:plain

まずサブフォントを追加するボタンをクリックしてから、Add Character  Rangeボタンと、Add Font ボタンをクリックして、Unicodeを入力します。

f:id:hiyokosabrey:20180525015925p:plain

ハイフンのあるところにUncode(ユニコード)を2か所に同じ値を入力します。

Range(レンジ)=範囲 なので、「ここから~ここまで」という指定ができるのですが、今回3文字しか作ってないのと、途中のグリフがないので、3文字分を単品で追加します。

 

Uniodeを入力する際は、U+00a9 という表記を16進数表記に直して入力します。

といっても、すでに 0x0000 となっているので、xの右側 4桁を書き替えるだけです。

f:id:hiyokosabrey:20180525014622p:plain

一応文字コード番号の調べ方は、Windowsだと、文字コードを使うと確認できます。

f:id:hiyokosabrey:20180525015539p:plain

 

サブフォントがセットできたら、保存してUMGのキャンバスを確認してみると、

f:id:hiyokosabrey:20180525020804p:plain

おお、いい感じになりました。

 

ここで、高さがおかしかったらFontForgeで調整すれば、どんなフォントが来てもバッチリです。

あまり見かけないですが、SM (ServiceMark)U+2120 というのも場合によったら必要になるかもしれません。

 

意外と手軽にグリフを補充できました。割と需要がありそうなので、このまま開発のたびにマイフォントとして育てていければいいなと思ってます。

 

おまけ

Photoshopをお使いのUIデザイナーの皆様にはぜひともご確認いただきたい設定があります。

環境設定(Ctrl+K)の「テキスト」という設定項目についてです。

f:id:hiyokosabrey:20180525022702p:plain

ここに、「見つからない字形の保護を有効にする」という項目があるのですが、デフォルトで チェックが付いているので、チェックを外しておくことを強くお勧めします。

これは表示しようとしたグリフを持たないフォントでも、代替フォントで表示して文字化けや、文字の欠けを防ぐ仕様です。ゲーム開発では、フォントの利用についていろいろ権利関係が厳しいので、チェックを付けない方が安全なのです。SonyさんやNintendoさんのハード向けのタイトルにうっかり Arial や MSゴシック が混入してたことが発覚したら・・・。チェックを外しておくことでグリフの有無を確認できるので、ローカライズ作業などでもメリットはあります。

 

 

ではでは

今回はこの辺で

ステキなフォントライフを!

 

 

 

 

 

 

 

UMGで ルビを振ってみる

f:id:hiyokosabrey:20180517231335j:plain

UMGでルビを振ってみようと思って試してみました。

途中諦めようかと思ったけど、なんとか形にすることができたので、メモっておきます。

今回日本語フォントとして、たぬき油性マジックという書体を使ってます。

 

仕組みとしては、まずルビ付きの文字をまず括弧的なもので分けたテキストを用意。

ここは人力。

それを分解してテキストブロックにしてUMGで表示します。

そのあと、ルビを置く場所を計算しながら置いていきます。

例えば、

f:id:hiyokosabrey:20180518213959p:plain

といった具合です。

 

で、UMGでTextBlockを並べるのですが、入れ物として2種類のパネルを使います。

f:id:hiyokosabrey:20180517235253p:plain

f:id:hiyokosabrey:20180518010435p:plain

CanvasPanel の方はルビ専用で、自由な場所に置くためです。一方の HorizontalBox は楽して左詰めするためです。

Size To Contentのチェックを付けていると、上図のようにバウンディングボックス(緑の枠)が小さくなりますが、ルビと本文の距離はここで調節します。

 

ブループリントからいじるので、 Is Variable のチェックを付けておきます。

キャンバスは以上です。

 

まず文字列を解析する関数を用意します。

この関数には、String型の入力ピンを一つと、本文とルビを配列で返すピンを追加します。

f:id:hiyokosabrey:20180519125150p:plain

Local変数も追加します。下図は、関数のピン設定とローカル変数。

f:id:hiyokosabrey:20180518011911p:plain

そして今回のキモとなる文字列分割ノード。

f:id:hiyokosabrey:20180519124901p:plain

まず 区切り文字=デリミタに設定した半角の { で配列に分解します。

{ から始まる文章が来るかもしれないので、 Cull Empty Srings のチェックは外しておきます。

 

このノードを通った分割後の文字列はこんな状態。デリミタは消滅します。

f:id:hiyokosabrey:20180518013407p:plain

 

ブランチノードで、デリミタが存在するか確認して分岐します。配列の数を調べれば分割されたかどうか判明します。

 

デリミタが無い=ルビが無い 場合、ルビに関する処理はしないので以下のようにします。

f:id:hiyokosabrey:20180518013930p:plain

分割があった場合は、 } が含まれるので、今度は Splitノードを使ってルビを分離します。

f:id:hiyokosabrey:20180519093329p:plain

わりとややこしい流れになったので、文字列が処理されていくイメージを図で説明するとこんな感じになります。

 

f:id:hiyokosabrey:20180519093043p:plain

 

Index に +1 して set Array Elem しているのは、 Insert ノードを使った直後はこうなっているからです。

f:id:hiyokosabrey:20180518230212p:plain

まだForEachLoopの Index は 1 のままなので、+1 しているという訳です。

 

で、最終的に2つの配列が整います。

f:id:hiyokosabrey:20180518230342p:plain

 

関数は以上です。

 

 

EventGraphに戻って、変数を一通り準備します。

f:id:hiyokosabrey:20180519095227p:plain

一番下の Stringは、Expose on Spawn にチェックを付けておきます。

f:id:hiyokosabrey:20180519123358p:plain

 

書体設定用の変数は、Slate Font Infoという変数タイプです。

一度コンパイルしてやるとDefaultValueからフォントやサイズが設定できるようになります。

f:id:hiyokosabrey:20180519094542p:plain

フォントの設定は、後からノードでも指定できるんですが、あらかじめ書体やサイズなんかが決まっていて途中で変更することが無い場合は、こうして変数の初期値として持たせておくとノードをつなぐときスッキリできるのでおススメです。

 

変数が用意できたら、文字を並べていくところを作っていきます。

f:id:hiyokosabrey:20180519104100p:plain

 用意しておいた関数から出てきた配列型の文字列を、準備した配列変数に保存します。

それを基にForEachLoopで順番に処理します。

上の方にあるConstruct Text というノードはそのまま探しても出てきません。

探すときはコレ。

f:id:hiyokosabrey:20180519104610p:plain

たいていのものはこのノードで実体化できるので、大変便利です。

Outerのところは、パネルの子供にすることが決まっているので、親になるHorizontalBoxをつないでいます。特に親がいない場合はSelfノードで大丈夫みたいです。

Classは、TextBlock をセットします。するとReturn Valueピンからは UMGの生TexBlockが生成されてくるので、いろいろ設定をしてやります。

これでルビを除いた本文だけが並べられて表示できるようになります。

ループ処理が終わったら、 Force Layout Prepass ノードを入れます。

f:id:hiyokosabrey:20180519105851p:plain

これは、TextBockの表示サイズを正確に取得するためです。

サイズが固定されてなくて、Size to Content にチェックがついているようなTextBlockやCanvasなどのWidgetパーツは、WidgetレンダリングされるタイミングとWidgetブループリントが処理されるタイミングがかみ合わないことがあって、サイズ取得できないことが多いです。

 

Widgetブループリントが、描画担当にテキストを渡して

Wブ「このテキスト表示してよ」

描画担当「分かった~」

Wブ「で、サイズは?」

描画担当「これくらい?」

Wブ「ほんとに?  ちょちょ も1回 Pre-passで確認してよ」

 

 ってことだろうと勝手に想像してます。

 

つぎにルビの表示処理です。

そのまえに、本文のTextBlockのサイズをチェックして加算するマクロを用意します。

f:id:hiyokosabrey:20180519113404p:plain

単純にTextBlockの幅を自身に加算してRubyPosition変数を更新していきますが、ルビで必要なのは、ルビを振る対象のTextBlockの幅を1/2したサイズだけが必要です。OffsetCenter変数にはそのまま入れるので常に上書きすることになります。

 

グラフに戻って続きを作ります。

今度は、ルビ用の配列変数をForEachLoopで処理していきます。

マクロで、本文のTextBlockの幅を調べて加算しつつ、ルビがあるかどうかをチェックします。

f:id:hiyokosabrey:20180519113831p:plain

ルビ用の配列に空(Null)を入れていたのはこのためです。ルビがあろうとなかろうと本文は並べられます。どのTextBlockがルビ振り対象だったかを覚えておくためには単にに別の配列を用意して同じ順番にルビを入れておけばいいよね?っていう発想です。

常に座標だけは計算しておきたいので、マクロをブランチノードの前に置いています。

ルビが見つかったら、本文と同じ要領でTextBlockを生成して、フォントの設定をします。

文字のレイアウト設定なんかもあるのでちょっと大きくなってます。

f:id:hiyokosabrey:20180519114904p:plain

最後のSet Positionノードで、ルビの位置がセットされます。

 

仕上げに、EventTickに、あのForceLayoutPrepassノードをつないでおきます。

f:id:hiyokosabrey:20180519115159p:plain

ちょっとしつこい感じですが、いろいろ試してみてTickでもやった方がいい結果になったのでつなぐことにしました。毎フレーム処理されるのは負荷が高いので、本文の表示が終わったタイミングで処理が走り始めるようにしています。

なぜか、ルビの表示処理が終わって、isActive を false にすると、ルビの位置がずれるのです。ずっとTickが走り続けるのが気になるのですが、今のところ他の解決策が思いついていないので、情報をお持ちの方はネットに公開していただけると助かります。

 

これでルビ付きテキスト表示のWidgetは完成です。

 

複数行を処理してルビ付きテキスト表示するためのWidgetを用意します。

キャンバスの適当な位置に VerticalBoxパネルを配置します。

f:id:hiyokosabrey:20180519120727p:plain

Size To Content と Is Variable にチェックを付けています。

配列変数を一つだけ用意します。受け取った文字列を配列にして保持するためのものです。

f:id:hiyokosabrey:20180519120936p:plain

String型なのにTextという名前を付けるのためらったのですが、大本の「文章」が渡されてくることを考えて、あえてTextArrayとしました。アイコンの色と形で分かるのがビジュアルスクリプトの素晴らしいとこだと思うので、混乱は無い、と信じたい・・・

 

で、受け取ったテキストは以下のような状態で受け取ります。

f:id:hiyokosabrey:20180519121656p:plain

改行位置は赤い矢印 の箇所。

うしろの方のしずかな空で、いきなり音がしましたので
シグナレスは{急|いそ}いでそっちをふり{向|む}きました。
ずうっと{積|つ}まれた黒い{枕木|まくらぎ}の向こうに、あの{立派|りっぱ}な{本線|ほんせん}のシグナル{柱|ばしら}が、
今はるかの南から、かがやく白けむりをあげてやって来る{列車|れっしゃ}を{迎|むか}えるために、
その上の{硬|かた}い{腕|うで}を下げたところでした。

 

宮沢賢治の「シグナルとシグナレス」より。

青空文庫からコピペさせていただきました。

 

この改行を分解して配列にします。

その関数が以下。再び Parse into Arrayノードの出番です。

f:id:hiyokosabrey:20180519122255p:plain

最後のSet Padding は、行間の調整用です。

下は Construct Object from Class ノードです。作っておいたルビ付きテキストWidgetをセットします。アセットも生成できるので、Create Widget とほぼ同じ。

f:id:hiyokosabrey:20180519122735p:plain

 

以上でWidgetは完成です。

テスト表示用にレベルブループリントを編集します。

f:id:hiyokosabrey:20180519123705p:plain

 

表示してみると、冒頭のキャプチャになりました。

いろいろ試してみました。

f:id:hiyokosabrey:20180519130912p:plain

フォントにいいのが無かったので、まったく迫力出ないですね。

再び青空文庫より。

f:id:hiyokosabrey:20180519135212j:plain

夢野久作の「ドグラ・マグラ」より。

もうノベルゲームが完成した感があります。

 

なんとかルビが付くようにできました。

もっといい方法があるぜよ、という方がおられればぜひご教授いただければ嬉しいです。

 

ではでは 今回はこの辺で

ステキなルビ振りライフを!

 

 

 

[3D]シンプルなリストメニュー作ってみる

前回のタブっぽい何かに、リストメニューっぽい何かを追加してみます。

f:id:hiyokosabrey:20180505224715j:plain

背景のマテリアルにPARAGONのアセット使わせていただきました。

 

その前に前回のマテリアルで、大事な設定を見つけました。

UI 表示では フォグの影響を受ける必要はないので、Apply Fogging のチェックを外してみました。

f:id:hiyokosabrey:20180505112157p:plain

すると、Intructions(命令)の数が減ったのです!

f:id:hiyokosabrey:20180505112803p:plain

f:id:hiyokosabrey:20180505112814p:plain

頂点シェーダの処理が約1/2、TextureSamplersの数も1/4になったので、これは効果アリですね。次回から確実に外していこう。

 

では、リストメニュー用のスタティックメッシュを用意します。

Blenderで↓のようなメッシュを作りました。

f:id:hiyokosabrey:20180505113546p:plain

下にある黒っぽいのはドロップシャドウ用のメッシュです。2面のポリゴンで1つのオブジェクトになっていて、こうことができるのがスプライトにない強みですね。作るときは1枚だけ作って複製し、ずらして統合します。影のカラーを付けたいので頂点カラーを付けています。

 

ちなみに作業用のテクスチャは以下。等間隔に並べます。

f:id:hiyokosabrey:20180505123600p:plain

この色分けはUV範囲を分かりやすくするためにレイヤーで色を載せています。この色分けに沿ってUVの頂点をきっちり当てます。

f:id:hiyokosabrey:20180505123854p:plain

エンジンにインポートする際は、グレースケールにして、TGA形式にします。

f:id:hiyokosabrey:20180505123615p:plain

 

メッシュはFBXでエクスポートします。流れは前回の記事と同じですが、頂点カラーを有効にする必要があります。まずは Import Settings でやる場合は、以下の場所にあります。

f:id:hiyokosabrey:20180505124833p:plain

 

インポートした後に有効にすることもできます。その場合は StaticMeshエディターの右のDetailsタブの中にあります。

f:id:hiyokosabrey:20180505125110p:plain

変更したら、Assetメニューから Remport(再読み込み)すれば反映されます。

f:id:hiyokosabrey:20180505125321p:plain

 

テクスチャインポートしたら、マテリアルを作成します。

f:id:hiyokosabrey:20180505132010p:plain

 

頂点カラーを使うには 専用のノードが用意されています。そのまま Emissive Color に渡してもいいのですが、ブループリントから色味をいじりたいので、MultiplyノードでVectorParameterノードを掛けています。

f:id:hiyokosabrey:20180505130420p:plain

 

リストの文字は、UVの位置をずらしてバリエーションを出します。

f:id:hiyokosabrey:20180505132057p:plain

今回移動するのは縦方向、Vの値だけが変化すればいいので、Uの値はそのままにします。

ちなみに Append は合成、Add は加算です。

A と B を Append すると、 (A, B) になって

A と B を Add すると、 A + B になります。

 

白いラインが全部一緒なので、慣れないと分かりにくいのですが、上の場合、

TexCoordから出てるのが、(U, V) の Flort2 または Vector2 とよばれる型。

左端の2つのノードは 単品のFloat型で、これを Append でくっつけて、

(0, OffsetV) にして、Add ノードで、(U, V) に加算しています。なので、

(0, 0.5) + (0, 0.25) だと (0, 0.75) になるのです。この単品の float が何本になってるかをノードの前後で把握することのが、マテリアル攻略の助けになります。

ちなみに下の例では、エラーにはなりませんが・・・

f:id:hiyokosabrey:20180505132710p:plain

(0, 0) に対して 単品の float を足すので、OffsetV = 0.25 だとしたら、

(0.25, 0.25) になります。これではUVが斜めに移動することになります。

 

マテリアルができたので、次にマテリアルインスタンスを作ります。

 マテリアルのアセットアイコンの上で右クリックしてコンテキストメニューから選択します。一番上にあります。

f:id:hiyokosabrey:20180505225010p:plain

マテリアルインスタンスにすると、仕込んでおいたパラメータのみ触ることができるようになります。(チェックボックスにチェックを付ける必要があります)

f:id:hiyokosabrey:20180505225433p:plain

文字を変更するのはUV値のVの方なので、パラメータ ”OffsetV” の値を変更します。

今回は48px ÷ 512px = 0.09375 が間隔なので、パラメータは以下のようになります。

f:id:hiyokosabrey:20180505230933p:plain

 

テクスチャに並べておいたテキスト分のマテリアルインスタンスを用意します。

いまのところコンテンツブラウザは以下のような状態。

f:id:hiyokosabrey:20180505231243p:plain

 等間隔に並んでいるので計算させた方がよさそうに見えますが、ゲーム開発においてメニュー項目なんてのは変更されるのが常です。さらにイベント用ROMなど特殊な状況のパッケージを作る際にも意図的に変更することがあります。このようなアセット構造にしておくことで、プログラマーとデザイナーとで分業しやすい状態にできるのでオススメです。

 

ブループリントアクターを用意します。

f:id:hiyokosabrey:20180506170156p:plain

StaticMesh とChildActor をAdd Componentボタンから追加します。

f:id:hiyokosabrey:20180506031559p:plain

追加しただけだと空っぽなので、Static Meshには さきほどインポートしたMeshアセットと対になるマテリアルインスタンスをセットします。

f:id:hiyokosabrey:20180506102851p:plain

 

最後の Child Actorコンポーネント には、前回の記事で作ったブループリントをセットします。

f:id:hiyokosabrey:20180506103551p:plain

 

Child Actorコンポーネントは、そのままだと中身にアクセスできないのでConstruction Script 内でキャストして変数化しておきます。

f:id:hiyokosabrey:20180506102633p:plain

(なんかちょっと不思議な感じ、間違ってるのかな・・・)

続きを組む前に、関数を2つ用意。

 

 見た目をデフォルトにする関数と、

f:id:hiyokosabrey:20180506111409p:plain

f:id:hiyokosabrey:20180506111154p:plain

 

見た目をフォーカス状態にする関数。

f:id:hiyokosabrey:20180506111421p:plain

f:id:hiyokosabrey:20180506111204p:plain

 

ConstructionScript 内で表示位置と状態のセッティングは済ませておきたいので、

StaticMeshComponentを配列変数にして、そこから ForEachLoop でいろいろセット。

f:id:hiyokosabrey:20180506114230p:plain

ループ処理の前後どちらでも問題ないと思うけど(上図では後)、配列に仕込んだ数を変数に持たせておきます。

 

準備ができてきたので、前回作ったタブっぽいウィンドウのブループリントを再び編集します。

f:id:hiyokosabrey:20180506170306p:plain

イベントディスパッチャーを追加します。

f:id:hiyokosabrey:20180506164617p:plain

作ったイベントディスパッチャーは、アニメーションの終了を通知するためのもので、TimeLineノードのCompleteピンにつなぎます。

f:id:hiyokosabrey:20180506164853p:plain

 これでこのブループリントは編集終了。

 

次はこのイベントディスパッチャーをバインドしてやります。

 

再び今回のBP。

f:id:hiyokosabrey:20180506170128p:plain

 

f:id:hiyokosabrey:20180506171016p:plain

 これで、ウィンドウの出現アニメーションが終わるのを待つことができます。

出現が完了したら、カスタムイベントで受け取って、リストメニューを表示する、という流れです。ここでリストのフォーカス位置を管理するための変数 int型 をひとつ用意しています。上図の FocusIndex。

 

右下の部分は、このあと何度か登場するので、関数にしてしまいます。

f:id:hiyokosabrey:20180506190940p:plain

まとめて選択しておいて、右クリック > Collapse to Function を選びます。

できた関数ノードを編集して、Pure型にしてみます。

f:id:hiyokosabrey:20180506191422p:plain

ノードが変化します。

f:id:hiyokosabrey:20180506191616p:plain

 今フォーカスされてるやつをGetするだけの関数だけど、こうしておくことで、ノードもスッキリして、名前で何をしてくれるかわかるし、関数の中にチェックの仕組みも入れやすくなります。

例えば下の例は StaticMeshComponentの配列から正しく取り出せるかチェックする場合。

f:id:hiyokosabrey:20180506211702p:plain

 

で、リストのフォーカスをくるくると切り替える仕組みをカスタムイベントで組みます。

f:id:hiyokosabrey:20180506231026p:plain

 このイベントの Inputs(引数)は int型で、+1-1 を受け取ります。

 

 ブループリントはこれで一応完成です。

 

さっそくレベルブループリントからテストしてみます。

f:id:hiyokosabrey:20180506213255p:plain

左の Set View Target with Blend ノードは、任意のカメラに切り替えるときに使います。Spawn Actor from Class ノードを使ってActorブループリントをシーンに呼び出します。

f:id:hiyokosabrey:20180506213641p:plain

キー入力でテストしてみたので、Inputノードは カーソルキーの ↑(Up)↓(Down)です。

再生してみると、

 

f:id:hiyokosabrey:20180506225458g:plain

GIFが重くて上げられなかったので2つに分けました。

f:id:hiyokosabrey:20180506225543g:plain

 

 うまく動いてくれました。

PostProcess の影響を受けるので、カラーのコントロールが難しいですが、UMGと大して変わらない印象です。UVアニメーションで凝ったことができるのと、アルファの透明部分をカットして描画負荷を軽くしたり、UVがレクト(長方形)じゃなくてもいので、テクスチャを節約できたり、頂点カラーが使えたりと、メッシュでUIパーツを作成できると、いろんな表現ができるのでとても楽しいです。

個人的に、お手軽さではUMGの方に軍配が上がりますけどね。

 

ではでは今回はこの辺で

ステキな[3D]UIライフを!