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

みつまめ杏仁

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

わりと本気のコンボカウンター 《完結編》

いよいよ動作確認です。

前回の記事はこちら

わりと本気のコンボカウンター 《準備編》 - みつまめ杏仁

わりと本気のコンボカウンター 《UMG編》 - みつまめ杏仁

わりと本気のコンボカウンター 《Widgetブループリント編》 - みつまめ杏仁

 

一揃いのアセットができたので、テストしてみます。

テスト用のレベルを開いた状態で、エディタを開きます。

f:id:hiyokosabrey:20161009230625p:plain

 

まずはカウント用の変数を一つ用意。Int型です。

CreateWidgetから始めます。

CreateWidgetの ReturnValue ピンの上で Promote to Variable を選ぶと簡単に変数化できます。とりあえず表示位置を大まかに決めておいて、あとはバインド祭り。

f:id:hiyokosabrey:20161009231355p:plain

Widgetの中に仕込んでおいた イベントディスパッチャーにバインドします。

バインドは「紐づける」という意味合いです。四角いピンとカスタムイベントをつないでおくと、Widget内でイベントディスパッチャーがCall されたタイミングでここに通知が来て、カスタムイベントが作動するというしくみです。

CreateWidgetした側は、好きなタイミングでWidgetに干渉できるのに対して、CreateWidgetされた側からは逆の干渉ができません。そこで用意されているのが、このイベントディスパッチャーを使ったデリゲートインターフェイスという2つの仕組みです。

EventDispatcher をCallしてるノードと、Bindしてるノードにマウスカーソルを重ねると

f:id:hiyokosabrey:20161009234141p:plain

デリゲートという用語が出てくるのが分かります。

今回インターフェイスは使っていませんが、これもGUIにはとても相性がよいです。

 

つぎに、カウントアップの呼び出し部分。

スペースキーを押すとカウントするようにしています。

f:id:hiyokosabrey:20161009235039p:plain

最後にWidgetの関数に値を渡して完成。

 

再生してテストしてみましょう。

f:id:hiyokosabrey:20161010002537j:plain

f:id:hiyokosabrey:20161010002546j:plain

f:id:hiyokosabrey:20161010002552j:plain

f:id:hiyokosabrey:20161010002558j:plain

動画を貼りたかったのですが、直接はダメっぽいので諦めました。

 

消え方が派手だったり、確定した時の演出があると、最終のカウントがよりわかりやすくなります。

 プレイヤーは視界の端で見てるので、多少派手なくらいがちょうどいいです。

 

というわけで

わりと本気で作ってみたコンボカウンターです。

デザイナーだけでこのようなモックアップを作ってテストしてもらい、プログラマに組み込みを依頼する流れでいけば、小さなイテレーションループで済みそうですがいかがでしょう。

 

ではでは

ステキなカウントライフを

 

 

 

 

わりと本気のコンボカウンター 《Widgetブループリント編》

続きです。

 前回の記事はこちら。

 

わりと本気のコンボカウンター 《準備編》 - みつまめ杏仁

わりと本気のコンボカウンター 《UMG編》 - みつまめ杏仁

 

 

Widgetブループリント

絵的な素材が用意できたところで、いよいよブループリントに手をつけていきます。

まずブーリアン型の変数を一つ用意。これは、「HITs」と下敷きのアニメーションを初回と2回目以降とで分けるためのものです。これを 初めから置いてある、EventConstruct ノードにSetでつないで、初期値を false にしておきます。(①)

f:id:hiyokosabrey:20161008220412p:plain

最後に準備用の関数をつないでいます。(③)

Add to Viewport されるたびに、この関数が実行されるのは無駄なので、DoOnceノードを間に入れておきます。(②)

このセットアップ関数の中身は以下。

f:id:hiyokosabrey:20161008221211p:plain

キャンバスに置いたImageパーツはマテリアルにパラメータノードを仕込んでいるので、パラメータに値を渡していじることで、カラーやUVを変えることができます。そのためには、Get Dynamic Material ノードが必須です。このノードにはReturnValue という出力ピンがあるので、その内容を配列に積んでおきます。

扱い方が少し違うので、「HITs」だけは配列にはしません。

このGet Dynamic Material の操作は、マテリアルを操作する直前で行ってもいいのですが、私はReturnValue(戻り値)を変数化しておくこの方法をよく使います。

メモリは必要になりますが、なんとなく処理コストが安くなる気がします。

 

次に 新たに変数を3つ追加します。

f:id:hiyokosabrey:20161008223322p:plain

 

カウンターを表示する関数を作っていきます。

この関数はInteger型の値をひとつもらって、それを桁に分解して表示するという内容です。いつ呼ばれるかは、プレイヤー次第なのでわかりません。コンボ受付中はカウントアップするので問題ないのですが、受付が終了してフェードアウトの最中に呼ばれると問題です。かといってフェードが終わるのを待たせるのは、ユーザビリティ的に問題アリです。

そこで、フェードアウト中に呼ばれたら、フェードアウトのアニメーションを止める処理を入れます。

f:id:hiyokosabrey:20161008224348p:plain

別の場所でフェードアウト用のタイマーをセットしていて、そのタイマーをコントロールするためにTimerHandle型の変数を利用しています。

今は↓この部分です。

f:id:hiyokosabrey:20161008225159p:plain

 

次に受け取った数字を桁に毎に分解する関数を作ります。

一、十、百、それぞれの桁の有り無しを判定して、あれば0~9の数字を取り出し、なければ  -1 にします。

先に作っておいた配列変数 DigitNumArray に 桁毎の結果を入れていきます。

f:id:hiyokosabrey:20161009105209p:plain

桁を分解する方法は、割り算(÷)と剰余(%)のノードを使います。

 

f:id:hiyokosabrey:20161009110955p:plain

 Int型同士の割り算は、小数点以下は切り捨てになります。

 

 配列の中身(要素)を変更するのは Set Array Elem ノードを使います。

この Set Array Elem ノードですが、あらかじめ要素が存在しているのが前提です。

あらかじめ配列の要素を用意する方法はいくつかあります。今回はノードを使わずにセトしました。配列を作ったときの初期値です。一度コンパイルすると追加できます。

f:id:hiyokosabrey:20161009112958p:plain

ちなみに、Addノードは新しく要素を追加するときに使うもので、何度も呼び出される関数の中に置くと要素が増えることになるのと、追加する順番に注意を払う必要があります。

 

続きに、できた関数をつないで、さらにカウント数に応じてカラーを変える仕組みをつなぎます。

f:id:hiyokosabrey:20161009113748p:plain

関数内では、ローカル変数という使い捨ての変数を使うことができます。

カラーを計算して利用した後は覚えておく必要はないので(この関数の外では役に立たない)ローカル変数を新しく作っています。

今回のカウントは 999まで表示可能ですが、カラーは100以上で変化しないようになっています。精度と調整のしやすさを考えて0~200でクランプします。その値を InverseLerpノードで割合に変換します。

f:id:hiyokosabrey:20161009185924p:plain

例えば 100 だと InverseLerpノードは  0.5 を返してきます。↑の図で、ちょうど赤から紫に変化するあたりです。InverseLerpノードは 指定した範囲のどの辺にいるかを割合で返してくれる便利なノードで、マテリアルのパラメータとして相性ばっちりです。

上の例では、コンボ数が 20、40、60、80、100 を越えるごとに色が変わります。

紫色の次がいい色にならなかったので、100で変化が止まっています。

この辺は自由に加減してみてください。

 

というわけで今↓ココです。

f:id:hiyokosabrey:20161009190634p:plain

次に進みます。

各桁の表示部分です。すでに数字を桁毎に分解してあるので、配列からGetノードで取り出しつつ、アニメーションの再生をマクロを使って処理しています。

f:id:hiyokosabrey:20161009191235p:plain

マクロは同じことを何度もする場合にラクちんなので積極的に利用します。

上記のマクロは3つとも同じ内容ですが引数を変えています。

マクロの中身はこうなっています。

f:id:hiyokosabrey:20161009192113p:plain

さらにマクロがあります。

受け取った数字から テクスチャのUVを求めて、0未満(-1)だったら 0.0 を、0以上だったら 1.0 をパラメータにしてマテリアルにセットするマクロです。

f:id:hiyokosabrey:20161009192445p:plain

 Set Vector Parameter Value ノードはベクター型のパラメータで、LinearColorの形で値を渡します。セットアップ関数で作っておいた Material Instance Dynamic型の配列からGetノードで取り出してつなぎます。

 

これで数字部分の表示は完成です。

f:id:hiyokosabrey:20161009193809p:plain

 

次に HITs の表示です。f:id:hiyokosabrey:20161009194717p:plain

色の変更と、アニメーションの分岐、フラグのセットをしています。

 

この後、タイマーのセットをするのですが、その前に用意するものがあるので、いったんこの関数の編集を止めます。

 

Event Dispatcher(イベントディスパッチャー)を2つ用意します。

f:id:hiyokosabrey:20161009210637p:plain

コンボカウントの受付終了と、退場演出のフェードアウトが終わったことを通知します。通知する相手はこのWidgetを CreateWidgetしたブループリントになります。

 

次に 退場演出のイベントを用意します。

カウントアップの関数から EventGraph に戻ります。

f:id:hiyokosabrey:20161009211806p:plain

赤いのはカスタムイベントです。作ったEvent Dispatcherを2つとも投入です。

Event Dispatcherはグラフにドラッグ&ドロップして取り出します。その際選択肢が出てくるので、Call を選択します。

f:id:hiyokosabrey:20161009212247p:plain

ようやくTimerHandle型の中身が判明しました。フェードアウトのアニメーションが終了したことを通知するタイマーだったのです。

目覚ましが鳴る前に起きてしまって、うっかりタイマーを止めずに顔を洗っていると鳴り出してイラッ・・・みたいな状況を避けるためのものです。

 

ここで、先ほど編集を中断したカウントアップの関数に戻ります。

いよいよラストです。

f:id:hiyokosabrey:20161009213033p:plain

f:id:hiyokosabrey:20161009213619p:plain

CreateEvent ノードは、作成済みの関数やイベントを選ぶカタチになるので、いったん中断したというわけです。

 

おつかれさまです。これでWidget完成です。

次回は、このWidgetを呼び出すところを仕上げて終了です。

 

 

 

 

わりと本気のコンボカウンター 《UMG編》

わりと本気です。コンボカウンターです。ということで前回の続きで用意したマテリアルをUMGにセットしていきます。

 

limesode.hatenablog.com

レイアウトする

f:id:hiyokosabrey:20161009215321p:plain

Widgetブループリントを作ったらさっそくパーツを配置していきます。

全体の位置調整用にCanvasPanelをひとつ追加します。

f:id:hiyokosabrey:20161008191027p:plain

DetailsタブのSize to Contentにチェックを付けておきます。

f:id:hiyokosabrey:20161008191442p:plain

これは中身に応じてサイズを変えるという仕様になります。

 

続けてImageパーツをこのキャンバスの子供として追加します。

999の3桁まで表示するので3つ、HITsの文字に1つ、下敷きに1つ。全部で5つを追加して並べます。名前も変更します。Digit は「桁」のことです。

f:id:hiyokosabrey:20161008192242p:plain

DetailsタブのAppearance > Brush > Image から、それぞれのマテリアルをセットします。

f:id:hiyokosabrey:20161008192624p:plain

テクスチャに仕込んだ大きさに合わせてサイズを設定したら、いい感じに並べつつ、ZOrderの数値で重なりを調整します。

f:id:hiyokosabrey:20161008192341p:plain

配置は完了。

 

アニメーションをつける

次にアニメーションを作成します。

今回用意したのは5つ。

f:id:hiyokosabrey:20161008193231p:plain

動かすのは、Slot ではなく、Render Trasform を動かします。

f:id:hiyokosabrey:20161008194018p:plain

f:id:hiyokosabrey:20161008194026p:plain

自由にアニメーションを付ければOKです。

遅くても 0.25 秒以内がオススメ。

例えば最初の登場アニメーションはこんな感じです。→ [ _IN_Hits ]

f:id:hiyokosabrey:20161008194922p:plain

透明な状態から不透明にしつつ移動してきます。

これを毎回やるとちょっとウザイので、2回目以降のアニメーションを用意しています。→ [ _UP ]

 

今回退場は透明にしてフェードアウトさせました。

実はここが今回手こずった部分です。

f:id:hiyokosabrey:20161008200202p:plain

パーツをすべて透明にするのですが、このアニメーションを再生すると、コンボ数が1桁の場合でも、10と100の位の数字が現れてしまうのです。

かといって、桁数に合わせて同じような退場アニメーションを何個も作りたくない。

というわけで前回のマテリアルに仕込んだスイッチが役に立つのです。

 

UMG編はここで終了です。

次回はブループリント編です。

 

 

 

 

わりと本気のコンボカウンター 《準備編》

ちょっとガチなコンボカウンターを作ってみようと思い立って始めてみたら、意外に時間がかかってしまった。まぁほとんど寝落ちが原因だけど・・・

f:id:hiyokosabrey:20161008005130p:plain

コンボカウンターは格ゲーではお馴染みの表示です。アクションゲームやシューティングゲームでも見かけます。ただ数字でカウントするヤツですが、いざ作ってみると奥が深いんです。

今回作ったカウンターの機能は以下。

・登場と退場の演出

・最後の更新から一定時間待って更新されなかったら消える

・一定のヒット数毎で文字の色を変える

・999までカウント表示可能

f:id:hiyokosabrey:20161008010219p:plain

 

 

おおまかな処理の流れは以下。

 

①常駐系の表示物なので、まずは CreateWidget してBindだけ済ませておく。

このBind(バインド)は表示終了の通知を受け取ってViewportから削除するため。

 

②ゲームが始まって、いざ表示開始になったら、ここでAdd to Viewport 。

 

③変数をカウントアップしつつ、同時にWidgetの中の関数に渡して数字を更新。

 

④一定時間更新が無かったら、終了通知を送ってViewportから消しカウント用の変数をリセット。

 

あとはプレイ終了まで必要に応じて、②~④を繰り返します。

 

わりとボリュームがあるので、数回に分けて書いていこうと思います。

 

テクスチャの準備

主役となる数字。

サイズは 512x256

f:id:hiyokosabrey:20161008114046p:plain

↓はアルファチャンネル。

f:id:hiyokosabrey:20161008011513p:plain

インポート設定で、Clampにします。

 

f:id:hiyokosabrey:20161008114035p:plain

 

 ↓カラーチェンジ用  1024x32

f:id:hiyokosabrey:20161008012353p:plain

ちょっとサイズが大きめ(=256x128)ですが、色と範囲の調整がデザイナー的にものすごくラクチンです。色の境界がシャープになるようにインポート設定を調整します。

 

機能的にはこれで足りるのですが、視認性を上げるために下敷きを用意しました。

左がRGB、右がアルファチャンネルです。上部にあるグラデーションはオマケです。

f:id:hiyokosabrey:20161008123546p:plain

 

数字のテクスチャには仕掛けがあります。

まずはUVの範囲とサイズ。

f:id:hiyokosabrey:20161008102306p:plain

ピクセルの座標をUV値に変換する場合は、テクスチャのサイズで割ってやります。

タテならタテ、ヨコならヨコです。例えば ↑の図で128pxが2か所あります。

数字のタテは 128÷256 で 0.5、 HITs のヨコは 128÷512で 0.25 という具合です。

(いつもこの辺りを教えるとき、小数点で渋い顔をされる方がほとんどです)

左上を基準として、ピクセルの量をイメージすると分りやすくなると思います。UV値は左上が(0,0)で右下が(1,1)です。ようするにタテとヨコそれぞれで、場所やサイズを割合(%)で指定する感じです。

私はいつでも手元にソーラー電池で動く電卓を置いております。

 

さてさて

仕掛けというのは各文字の左と上に余白を空けていることです。

f:id:hiyokosabrey:20161008103845p:plain

8px分をキープ。この余白を使ってドロップシャドウを再現します。

 

マテリアルの準備

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

UMGで使用するので、MaterialDomain(マテリアル属性)はUserInterfaceを選択。

ちょっとゴチャっとしてますがこんな感じになります。

f:id:hiyokosabrey:20161008115943p:plain

テクスチャサンプルノードが3つありますが、一番上が、カラーチェンジ用で下2つが数字のテクスチャです。

真ん中ちょっと上の Constant2Vectorノード(キーボードの2を押しながらクリック)がドロップシャドウ用の数値です。8pxずらすので、UとVそれぞれで

8÷512= 0.015625、 8÷256= 0.03125 になります。

一番上の Tex Coordinate ノード(赤いやつ)のパラメータは、U方向に動かすのでかなり小さい値にしてます。とりあえず1ピクセル分以下です。『Tiling』はテクスチャの中から切り出すサイズだと思ってもらって問題ないと思います。1以上の値が入ると見た目に繰り返します(これぞタイリング)。

 

 次に「HITs」のマテリアル。

文字が固定でUVが変化したりしないので、少しだけシンプルになります。↑のマテリアルと共通する部分をコピペすると楽です。

f:id:hiyokosabrey:20161008122130p:plain

 

下敷きのマテリアルも用意します。

f:id:hiyokosabrey:20161008124336p:plain

テクスチャサンプルノードは2つもの同じものです。テクスチャの上の方にグラデーションを入れているので、その分ずらしたりしています。

 

 

テクスチャとマテリアルアセットの準備は以上です。

次回UMGでレイアウトするところを書いていきます。

ではでは

アセットを作らずにWidgetを作る 《おまけ》

前回の記事でWidgetブループリントで、テキストWidgetを好きなだけ作ってキャンバスに置く方法を書きました。

 

limesode.hatenablog.com

これを使って遊んでみました。正直何の役にたつか謎なので、暇つぶし程度にしかならない気がする・・・

 

まず前回の記事で最後の乗せたノードたちをマクロにします。

f:id:hiyokosabrey:20160925165225p:plain

まるっと選択して右クリック、Collapse to Macro を選択。

f:id:hiyokosabrey:20160927221958p:plain

 

ダブルクリックして編集します。

Construct Text ノードの実行ピンからドラッグして、Inputsと書かれたノードの上にドロップします。

f:id:hiyokosabrey:20160927222320p:plain

右の方の Outputs も同じようにつなぎます。

f:id:hiyokosabrey:20160927222741p:plain

EventGraphに戻って確認してみると下のようになっています。

f:id:hiyokosabrey:20160927223103p:plain

ここに引数戻り値のピンを追加します。

再びマクロの編集に戻ります。

Inputsノードを選択した状態で、Detailタブの中にある Newボタンをクリック →①

f:id:hiyokosabrey:20160927223602p:plain

変数のタイプは Integer (整数)を選択 → ②

適当な名前を付けます → ③

これが引数というやつです。

Inputsノードに引数のピンが追加されているので、そこからドラッグして To Text(Int) ノードを取り出します。

f:id:hiyokosabrey:20160927224247p:plain

下のようにつなぎます。

f:id:hiyokosabrey:20160927224501p:plain

次にOutputsの方。

Add Child to Canvas ノードの Return Value ピンからドラッグして、Outputsノードにドロップします。(ノードの真ん中付近にドロップ)

f:id:hiyokosabrey:20160927224829p:plain

マクロ完成です。EventGraphに戻ってみると下のようになってます。

f:id:hiyokosabrey:20160927225241p:plain

この辺で、マクロの名前を変えておきます。

たくさんテキストを作って動かすので、まず変数化します。

f:id:hiyokosabrey:20160927230319p:plain

Promote to Variable を選択すると変数が作られますが、いったんノードを削除します。

f:id:hiyokosabrey:20160927230616p:plain

グラフからノードを消しても、Variableリストには残っているので、選択します。

下のDetailタブで、名前を変更したら、配列化ボタンをクリック 。

f:id:hiyokosabrey:20160927231148p:plain

配列化できたら、これをグラフにドロップしてGetのカタチにします。

そこから Add ノードを取り出してマクロとつなぎます。

f:id:hiyokosabrey:20160927231514p:plain

Add ノードは、配列型の変数に対して行う処理で、配列にどんどん要素を積み込んでいきます。このままだと1回しか積まないので、ここに ForLoop ノードをつなぎます。

f:id:hiyokosabrey:20160927231911p:plain

これで、カウント 0~99 までの繰り返し、全部で100回繰り返します。

配列には 100個の要素が積まれることになります。

Loop Body から白線が途切れるまでを繰り返します。

 

前回の記事の最後の方で 『適当なキャンバス』 というのが登場します。

マクロにも出てますが、CanvasPanel_31 はこんなやつです。

f:id:hiyokosabrey:20160927232953p:plain

これをノードとして利用するので、 Is Variable のチェックを付けています。

f:id:hiyokosabrey:20160927233229p:plain

このキャンバスパネルに対して子供として100個のテキストWidgetをマクロでくっつけますが、座標の指定をしないと同じ位置に重なってしまいます。そこでポジション設定。

Graphに戻ります。

キャンバスパネルの大きさを計算で利用したいので保持する変数を一つ用意します。

Box 2D 型です。

f:id:hiyokosabrey:20160927233809p:plain

この変数にキャンバスパネルのサイズを取得して渡します。

まず変数をグラフにSetのカタチで ドロップ → ①

さっきマクロにつなげた ForLoop ノードと、EventConstructノードもつなげてしまいます。

左のピンから Make Box2D ノードを取り出す → ②

f:id:hiyokosabrey:20160927234423p:plain

キャンバスパネルをドロップ → ③

そのノードからドラッグして Slot as Canvas Slot ノードを取り出す → ④

ReturnValueピンからドラッグして Get Sizeノードを取り出す → ⑤

基本的にキャンバスなどのWidgetパーツのサイズを取得するには、③→④→⑤ の流れになります。

 

次に、

座標をセットするために Set Position ノードをつなぎます。マクロの ReturnValue からドラッグすると、Set Position ノードが見つかります。ここにGetSizeの結果の1/2をつないでおきます。サイズの半分ということで、「真ん中」になります。

f:id:hiyokosabrey:20160928000305p:plain

まだテキスト100個分の座標がコントロールできる感じじゃないので、配列変数を新しく追加します。今度は、Vector2D 型です。ここに100個分それぞれの値を入れて管理します。

f:id:hiyokosabrey:20160928001331p:plain

この配列変数をForLoopの最後につなぎます。

f:id:hiyokosabrey:20160928001613p:plain

最初の配列は、スロット型でテキストWidget100個分を動かすためのものです。で次ののVector2D型の配列は、テキストWidget100個分の移動速度と方向入れておくものです。

この配列にランダムな値を作って積んでいくようにします。ランダムと言っても一応計算して求めます。

f:id:hiyokosabrey:20160928220240p:plain

真ん中にある COSdSINd はサインとコサインを求めるノードです。

普通はラジアンで求めるというのを数学で習ったと思いますが、0~360の角度(Degree)からラジアン(Radien)を計算するのは、覚えていないと面倒です。ところがブループリントには 角度から サイン・コサインを求めるノードが用意されているのです。なんて便利!

f:id:hiyokosabrey:20160928221653p:plain

この計算は角度を適当に決めて円周の点(x,y)をサイン・コサインで求めた後、適当な半径(2.0~8.0)をかけているだけです。ということで細かい説明はひとまず置いておきましょうか。

これで準備はできました。

f:id:hiyokosabrey:20160928222201p:plain

 

あとは、動かすだけです。

Event Tick につないでいきます。

f:id:hiyokosabrey:20160928224555p:plain

この状態で100個分のテキストWidgetが動くのですが、制限を付けていないのでバーンと移動してそのうち消えてしまいます。

f:id:hiyokosabrey:20160928224957p:plain

 

そこで範囲を越えたら反射させます。

だいぶ説明が長くなってきたので、一気に載せてしまいます。

f:id:hiyokosabrey:20160928230134p:plain

f:id:hiyokosabrey:20160928230146p:plain

大きいので左右2枚にしました。

範囲をチェックするのですが、タテとヨコそれぞれの方向でチェックします。

まずヨコをチェックして範囲を越えていれば  (-1, 1.0)を掛けます。次にタテをチェックして範囲を越えていれば今度は (1.0, -1.0) を掛けます。

-1 を掛けることで反転することになります。反転したら、配列の中身を更新します。

最後に今の位置を調べてあるので、そこに配列の中身を足して 新しいポジションにします。

これで一応完成です。

テストしてみると、100個の数字が飛び交います。

f:id:hiyokosabrey:20160928231126p:plain

時間内にこの中から決められた数字をさがせ! というミニゲームができそうな・・・

 

作りはじめたときサイン・コサインを使わずに移動速度と方向を求めていたら、いい感じにならなかったので、サイン・コサインを使うことにしました。

f:id:hiyokosabrey:20160928231640p:plain

これで問題があるかと言われれば、 0に近い数字が出てきてしまうことです。サイン・コサインを使うと、どんな角度でも一定の速度で移動できるメリットがあります。シューティングゲームでは必須です。

スピードをランダムにするのをやめて固定値を入れてみると・・・

f:id:hiyokosabrey:20160928232254p:plain

f:id:hiyokosabrey:20160928232509p:plain

 これはこれでなかなかキレイです。弾幕シューティングを彷彿とさせます。

 

おまけのつもりが結構なボリュームになってしまった。

今回はこの辺にしておきます。

 

ではでは ステキなWidgetライフを!

 

 

 

 

アセットを作らずにWidgetを作る

Widgetで何か表示しようとすると、UMGでキャンバスにパーツを置いていきます。これはあらかじめ表示する数が分かっている場合ですが、数を必要に応じて動的に配置したいときは、別のWidgetブループリントをアセットとして用意しておいて、これをCreateWidgetノードを使って並べます。

f:id:hiyokosabrey:20160925155636p:plain

テキストを表示する際に色をつけたり、ボールドにしたりしたくなった場合にいちいちアセットから用意するのもなんだかな~・・・ と常々思っていました。

 

ありました。

ブループリントだけで自由に作る方法が。

Create Widget ノードを取り出してよく見ると、Construct NONE と書かれています。

そうか!?

 

ということで、さっそく実践。

まず変数を用意します。といっても正しくはクラスです。

Variablesのところの追加ボタンをクリックして、"text" で検索すると出てきます。

f:id:hiyokosabrey:20160925160302p:plain

上の図のように白い▲のところから Class を選択します。

Detailsタブから名前と初期値をセットするのですが、下のようになっているので焦らずにコンパイルします。

f:id:hiyokosabrey:20160925160728p:plain

適当に名前を付けて、一番下のプルダウンを TextBlock に変更します。

f:id:hiyokosabrey:20160925161009p:plain

これをグラフにドラッグ&ドロップします。

f:id:hiyokosabrey:20160925161340p:plain

ドロップしたクラスのピンからドラッグしてConstruct Object from Class ノードを取り出します。

f:id:hiyokosabrey:20160925161714p:plain

クラスからオブジェクトを作るぜ! というノードです。

f:id:hiyokosabrey:20160925161847p:plain

ノードのキャプションが Construct Text になっています。似てますね。

Outerピンに何もつながないでいると、コンパイルエラーになるので、Selfノードをつないでおきます。

f:id:hiyokosabrey:20160925162442p:plain

最後にReturnValueを適当なキャンバスパネルに Add Child to Canvas してやります。

f:id:hiyokosabrey:20160925162821p:plain

これが基本のフローです。

色とかフォントを変えるのはこんな感じ。

f:id:hiyokosabrey:20160925165225p:plain

端っこのAutoSizeは、有効にしておかないと、文字が欠けてしまってすべて表示されません。

 

この方法を使えば好きなだけ画面にテキストを表示できます。

ショットガンのヒットダメージ表示とかにも使えそうです。

 

Imageも同じ方法で大量生産できます。

 

ではでは

次回もうちょっと遊んでみます。

 

 

 

 

マテリアル操作で簡単アイコン切り替え

UMGのマテリアル操作でアイコンイメージを切り替える記事を前に書きました。

ちょっとだけラクする方法をひらめいたのでメモしておきます。

簡単といっても指定が楽になる程度ですが。

 

limesode.hatenablog.com

このときは、アイコンのUV値(テクスチャ内の場所)をそのまま配列にしていました。

f:id:hiyokosabrey:20160112205453p:plain

 小数点の扱いがちょっと・・・な感じです。

 

まず今回用に新しくテクスチャを用意しました。

512x256 の長方形です。

相変わらず、Webdingsという書体で構成しています。

 

↓RGBはこんな感じ。

f:id:hiyokosabrey:20160918001216p:plain

↓アルファチャンネルはこんな感じ。

f:id:hiyokosabrey:20160918001313p:plain

 

アイコン1個分の大きさは 80x80 です。今回長方形のテクスチャなのでTilingの値がUとVで異なります。

UV値を扱う場合、 値の範囲は 0.0 ~ 1.0 なので、

値を求めるときは  ( 移動量もしくはサイズ ÷ テクスチャサイズ )で計算します。

Uの値は 80 / 512 で 0.15625

Vの値は 80 / 256 で 0.3125

になります。

f:id:hiyokosabrey:20160918001757p:plain

半角のスラッシュは、プログラミングの世界では 『割り算』を意味します。

分数表記で 1/2 と書いたりしますが、そういうことです。

割り算のノードを取り出すときに使います。ちなみに掛け算は アスタリスクです。

 

3Dモデルを作る方々はこんなUVの計算なんか無縁なんですが、UIデザイナーは日々こんな小数点と闘っているのです。えへん。

 

で、この値をマテリアルに仕込んでいきます。

今回見た目に発光させたいので、Blend Mode を Additive にしました。

f:id:hiyokosabrey:20160918003249p:plain

まずは色を付けるところから。色を変えるためにベクター型のパラメータを2つ。

f:id:hiyokosabrey:20160918004439p:plain

 

つぎにUVを操作するとこ。

f:id:hiyokosabrey:20160918010345p:plain

ベクター型の中身である4つのFloat型、RGBA のうち、RとGをTilingの値としています。BとAをOffestにしていますがTilingと掛けているところが今回のポイントです。

マテリアルは以上で完成です。

 

前回の記事と同様にしてキャンバスに並べてブループリントから変更してやるだけなのですが、配列の値を変えます。その前にアイコンの並びを確認。キレイに並んでいれば配列を使う必要はないのですが、削除したり追加したりしているうちに制作終盤で下図のように不規則になることもあります。

f:id:hiyokosabrey:20160918100237p:plain

普通テクスチャ内でアイコンの場所が変わっても、アイコンを管理する番号(ID的な)は仕様的に変更することはしません。バグの元になります。なので、アイコンが順番通りに並んでいなくても、管理番号さえ変えなければ問題ないので配列が便利なのです。

 

今回、マテリアルに仕込んだ計算でこの場所の指定がラクになります。

左上のアイコンを(0,0)として右下のアイコンが(5,2) という形になります。

f:id:hiyokosabrey:20160918101013p:plain

 

配列にするとこんな感じ。メンテナンスするならどちらが簡単か一目瞭然です。

f:id:hiyokosabrey:20160918102218p:plain

アンリアルエンジンでは数値のフォームで四則演算が使えます。

左側の場合 一旦 0.15625 というベースの数字を [Ctrl] +[ C]キー でクリップボードに入れたら、あとは[Ctrl] +[ V]キーでペーストして、 *2 とか *5 を後ろに入力して[Enter]キーを押すと計算結果に変わります。

f:id:hiyokosabrey:20160918103127p:plain

テクスチャが長方形の場合、UとVでベースの数字が違うのと、アイコンのサイズとテクスチャのサイズを忘れた頃に編集することになると思うので、それなりに面倒です。

テクスチャをパッと見て、左から何個目、上から何個目って数えた方が早いです。

 

で、表示テスト。

f:id:hiyokosabrey:20160918104805p:plain

 

 ちょっと遊んでみました。

f:id:hiyokosabrey:20160918112925g:plain

カーソルキーでフォーカスを切り替えています。上下左右はループするすようにしています。

今回のマテリアル操作自体は、新しいテクニックではないです多分。単に自分で勝手に「そうかその手があったか」って盛り上がったので、記事にしてみました。

 

基本的な操作を習得するので問題ないですが、制作の工程を長い目で見ると、まだまだ効率化の余地はあるなぁ、と長年やってきて思うわけです。

 

ではでは、ステキなUVライフを!