みつまめ杏仁

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

続 ゲージUI を試すためのプロジェクトを作る

今回の内容は前回の記事のオマケ的なやつです

limesode.hatenablog.com

弾が当たると、ゲージが減るところまで作りました。今回マイナスにならないように「ゼロになったら」という判定を追加するのと、青キューブにリアクションを追加します。

 

体力がゼロになったら

ただのスタティックメッシュでしかなかった青キューブをブループリントにくるんで、StaticMeshActorというアセットにしました。コンテンツブラウザにアイコンが増えています。これを編集します。

アウトライナに並んでいる青キューブのところの Edit~ をクリックしてもOK。

 

ヒットを検出して体力を減らすイベントのところ

ここにスキマを開けます

マイナスしているところからドラッグして不等号記号  を取り出します

全角記号だとヒットしないのでご注意。

続けて判定して処理を分岐する Branch ノードを取り出しています。

下図のように割り込むかたちでつなぎます。

いったん -200 した結果が 0以上だったら true なので変数の値を更新してゲージも更新。0以下になったら false になります。

 

キッチリと 0 になるとは限りません。またゲージは完全にゼロになったことをプレイヤーに見せる必要があります。そこで false のほうは変数の値を強制的に 0 にしてゲージを更新するように CustomEventを複製してつなぎます。

さすがにつながりがややこしくなってきました。

同じ値を参照しますよという状況を意図的に表すために右端はラインが交差しまくってますが、分解すると下のようになります。

マテリアルは白いラインしかなくて処理の順番かつ値の流れになってますが、一方のブループリントは白いラインは処理が行われる順番を示すだけで中に何も流れていません。

色のついたラインは値(データ)のやり取りというか参照関係を示しているので、白いラインでつながったノードが処理するときに、ようやく内容がどうなっているかを見に行く、取得するイメージとらえるといいかと思います。

 

さてさて

これで体力ゼロになったときに、ゲージがマイナスにならないようになりました。

せっかくゼロかどうかの判定をしたので、それをフラグとして伝えるようにします。

ついでにイベントノードの名前も CustomEventのままだとカッコがつかないので改名します。CustomEventノードをダブルクリックしてみてください。

ノード名の下に Target is MyHUD となっているので、MyHUDが開かれます。

このカスタムイベントにピンを追加します。

エディタ右のDetailsパネルから Inputの項目を探します。右端のプラスボタンを押して追加されたら、IsDead と命名しておきます。これがホントの死亡フラグです。

カスタムイベントのノードが以下のようになります。

ついでに、Detailsパネルの一番上 Graph Node のところで改名します。

DrawGaugeとしておきます。Drawは描く、描画するという意味でよく使います。

確認用にPrintStringノードをつないでおきます。

PrintStringノードには IsDeadピンから直接ドラッグします。

途中にある

これは、型が違うモノをつなぐときに、変換してくれるキャストノードです。自動で挿入してくれるのでありがたいです。

一応、検索でも取り出せます。

"to ~" でキャストできる候補があれば出てきます。

今回は Boolean(ブーリアン=真偽値)型を String(ストリング=文字列)型に変換するので、結果は "true" か "false" になります。

コンパイルして問題がなければ保存して閉じます。

 

青キューブのブループリントに戻ってくると CustomEvent が DrawGauge に変わっていますね。

単語をくっつけていても勝手に ”わかち書き” してくれるのは文化だなと思うけどちょっと気になる。

2つあるDrawGaugeノードのうち、下側が体力ゼロの場合なので、こちらの IsDead にチェックを付けます。

これでコンパイルしてエラーがなければ保存してテストします。

 

弾が当たるたびに左上に文字が表示されます。

ゼロになったときにチェックをつけているので、false から true に変化すればちゃんと動作しています。

PrintString ノードで値の状況をチェックすることができるのでいつも大活躍です。

Append ノードと組み合わせるとさらに便利になります。

 

ちなみに

マイナスになったからといって、エラーになったりしないし、今のところ問題ではないですが、マテリアルでマイナスの値を利用するときには注意が必要です。特にカラーのRGBAはマイナスになると想定していない色味で描画されるからです。Lerpノード(線形補間: Linear Interpolate)も同じく0~1 の範囲で扱う前提になっています。

マテリアル側に  Clampノードを入れて対策することも可能ですが、値を渡す側、ブループリントで整えてやる方がいろいろと都合がよいケースが多いです。

 

 

HUDまでこのフラグが来たので、ゲージWidgetに伝えるには、ゲージWidget側で受け取るようにします。

Boolean型のピンを追加します。

これでゲージがゼロになったときにWidget側でゲージに演出を加えることができるようになります。また別の機会にでも書こうと思います。

この状態でも何も起こらないのでコンパイルします。

問題なければ保存して閉じます。

 

HUDブループリントに戻ってBooleanのピン同士をつないで完了。

これもコンパイルして保存したらテストしてみましょう。

 

 

ここから本格的におまけ

ゲージが動作するだけでは面白くないので、青キューブの体力がゼロになったときにカラーを変えるようにします。

グラフに StaticMeshComponent の Getタイプのノードを取り出します。

Widgetブループリントでやったとの同じような要領で、Dynamic Material Instance を作ります。

この ダイナミックマテリアルインスタンスを作るということは、何が目的なのかというと、個別にマテリアルを操作するためです。

アンリアルエンジンではマテリアル(シェーダー)は効率化のために共有されるのが基本。ゲームで再生される際に共有状態のままだと、変更がかかると共有している全てに同じ変更が反映されてしまいます。そのために一時的に独立した専用のマテリアルインスタンスを作って、書き換えても他に影響しないようにするためです。

Photoshopで スマートオブジェクトを複製するとき、「レイヤーの複製」を使った場合と、右クリックメニューから「スマートオブジェクトの複製」をした場合でふるまいが変わるのをイメージしてもらえるとわかりやすいと思います。

 

とりだした CreateDynamicMaterial ノードをつなぐのはここ

入力ピンは4つありますが必要なのは Target Element IndexSource Material で、Targetはすでにつながっているので残りは確認します。

エディタ左のComponentsパネルから 青キューブの本体 Static ~ をクリック。

今度はエディタ右の Detailsパネルを確認。

Materialsの項目に メッシュモデルにアサインされているマテリアルが並びます。青キューブは一つしかアサインされていないようです。たいていは質感やエフェクト用に複数アサインされています。

Element 0 しかないので Create~ノードの Element Index は 0 のままで問題なし。

このElement 0 にアサインされているのが DynamicMaterialInstance用の  Source Material ということになります。そこで、アイコンがいくつか並んでいるところ、フォルダと虫眼鏡のアイコンをクリックします。

クリックすると、コンテンツブラウザの表示が切り替わります。

マテリアルアセットがハイライトされている状態で
CreateDynamicMaterialInstanceノードのSourceMaterialに部分についている矢印ボタンをクリック。

これでこのノードのセットは完了。

仕上げに ReturnValue を ドラッグして Promote to Variable(変数に昇格)選択。

Mat_Cube と命名

これで、マテリアルのパラメータにアクセスできるようになりました。

 

タイムラインノードを取り出します。

ブループリント内にタイムラインを挿入できる素晴らしいノードです。

Widgetブループリントにもほしい。

 

このノードをダブルクリックすると専用の編集用のタブが開くので、カラーを遷移させるためのトラックを追加します。①②

 

Length はアニメーションの時間で単位は秒です。とりあえず 1秒にします③

マウスのホイールで横方向のスケールが変更できます。

開始時のカラーに青キューブの初期カラーを設定します④

遷移の最後のカラーを適当なカラーにします⑤

 

青キューブのカラーを調べるには、マテリアルアセットを開きます。

右上にパラメータがあります。Base Color という名前を憶えておきます。

右の青い部分をクリックするとカラーピッカーがポップアップします。

16進数のカラーコードをコピーしてクリップボードに入れます。

 

タイムライン編集画面の小さな■ (上がRGBで下がA 。Photoshopと逆)をダブルクリックすると

カラーピッカーがポップアップするので、クリップボードに入れたカラーコードをペーストします。

見た目に明るくなるのは仕様です。ちょっと調査が甘くて申し訳ないですが、各色のビット深度が 16bpp で扱われているようです。sRGBなどの補正された色空間に見慣れていると気になってしまいますよね。調整しにくい場合は、カラーピッカーの右上にあるカラープレビューを見ながら色を決めるといいです。

 

タイムラインの編集が済んだら、タブを切り替えて EventGraphに戻します。

体力ゼロになった方の処理につなぎます。

Play” はタイムラインを一度再生すると、再生中に割り込まれても最後まで再生します。

一方 "Play from Start" は、書いてある通り再生中に割り込まれるとタイムラインの頭から再生します。

ここは、青キューブの死亡が不可逆なので、Play につなぎます。

 

次にマテリアルに反映させます。

用意しておいた DynamicMaterialInstance型の変数 をグラフに取り出して①

SetVectorParameterValue ノードを検索して取り出したら②

TimeLineノードの Update とつなぎます③

ParameterName のフォームにマテリアルに用意されているパラメータ名を入力④

(スペースがあるのかアンダースコアなのかわかりにくいのがちょっと・・・パラメータの命名ルールはしっかりと管理したいものです)

あとは Valueピンと、タイムラインノードの NewTrack0 をつなげば完成⑤

 

TimeLineノードの Finish ピンは最後まで再生したら流れるので、アニメーションの終わりに何かするにはとても便利です。

たとえば物理シミュレーションを止めるとか。

この SetSimulatePhysicsノードで false にすると、カラーが変化し終わると同時に固まって動かなくすることができます。固まる場所によっては邪魔になったり踏み台になったりするので、ゲームのメカニクスってこういうところから生まれるのかもしれません。

 

コンパイルしてエラーがなければ保存して再生してみましょう。

 



この調子で、当たったときに色が変わるようにしてみましょう。

Timelineノードを新しく追加してつなぎます。

連続ヒットを想定して短めに設定。

当たった色から青キューブの基本色へと変化させます。

同じ要領でゲージ更新処理の上につなぎます。

今度は Play from Start にします。

 

これで弾が当たった時にわかりやすくなります。

 

さて、お気づきでしょうか?

当たった瞬間に色が変わりますが、最後ゼロになった瞬間は”青”から変化します。

最後だけは当たった色が再生されないのです。

ということで、タイムラインを編集。

当たった色から死亡カラーへと変化させます。

 

 

ゲージテスト用のプロジェクトとしては以上です。

いかがでしたか?やっぱりゲームにはリアクションがとても大事ということですね。

UI デザインはそのリアクションとしても機能するし、リアクションへの期待を持たせることもできるので、ささやかなデザインだとしてもプレイヤーにはそれなりに重要な情報となるのです。まぁ伝わらないこともあるので、そこはさっさと作って試してもらって反応を見るのが一番の近道。あまりデザインに時間をかけすぎないのも時には大事です。

ぜひ自作のゲージに差し替えてみたりして遊んでみてください。

まだいろんなゲージを追加して遊べるので、そのうち記事にしようと思います。

 

次回はプレイヤーがダメージを受けた時のゲージを記事にしようと思います。

ネタをくださいとお願いしていただいたものになります。

 

ではでは

素敵なゲージライフを!