最近UE4のマニュアルというかチュートリアルを書く機会があって、急いだせいかさすがに疲れました。でちょっとブログも休憩してました。
久しぶりに書きます。
格闘ゲームの体力ゲージは、ダメージを受けた瞬間に減らします。これは遅延があるとゲージがまだ見た目に残ってるのにK.O.判定されてプレイヤーは納得いかないからです。一瞬で減ったら減ったで今度は、どれくらいのダメージを受けたのか(減ったのか)が気になります。今の技をもう一度受けられるのか否か・・・ガードしても結構削られるな・・・とか考えます。そこでいつのころからかダメージゲージが採用されるようになりました。仕組みは単純で赤色のゲージを下に重ねて少し遅らせて減らすというものです。
UMGとマテリアルでちゃっちゃと作ってみましょう。
ちょっとGateを試してみたかったというのも今回記事を書くきっかけの一つです。
ゲージは過去記事で書いてますが、
もう一度おさらいの意を込めて書いておきます。
まずマテリアルから。テクスチャはグラデーションだけでいいので 256x16。
← 実寸
これを下のようにつなぎます。
右端のマテリアルドメインが UserInterfaceになってます。以前のバージョンだとSurfaceでした。
ValueStepというノードは、0~255諧調のグレースケールをパッキリと2諧調化してくれるノードです。そのしきい値を調整するのが、緑のスカラーパラメータです。ここではValueというパラメータ名にしました。あと、グレースケールを作り出してくれるのが左下の LinearGradientノードです。
これが、体力ゲージの本体です。
このマテリアルを複製してダメージ用のマテリアルを作ります。カラーが違うだけです。ここでつないでいるのは ConstantV3 ノードです。数字の[3]キーを押しながらクリック。
今回左から右に減るので、OneMinusノード(1-x)は無しです。
これでマテリアルができたので、Widgetを作成します。
まずは Image パーツをキャンバスに2つ配置します。
Anchorsは反転しやすいように中央上にしました。
Imageパーツは、テクスチャを直接セットできるほか、マテリアルもセットが可能なので、作ったマテリアルをセットします。
Details > Appearance > Brush > Image
ZOrderというパラメータで、重なり順を指定できるので、同じ位置にピッタリ重ねます。(下図はわざとずらしてます)
次にWidgetブループリントを編集します。
マテリアルのパラメータに対してかなり頻繁にアクセスします。そのたびにいちいちGetDynamicMaterialするのは処理がちょっともったいないので、変数化しておきます。
最初からWidgetに置かれている EventConstruct ノードは、ビューポートに置かれた瞬間に一度だけ処理されるので、ここにつなぎます。
Float型の変数を2つ用意して上図の続きにつなぎます。
ここで初期値 1.0 を入れておきます。
次に関数を作ります。
UpdateVitalValue という名前にしました。
Set Scalar Parameter Valueノードは、マテリアルインスタンスダイナミック経由でマテリアルの中のパラメータにアクセスするノードです。
基本的にこの関数に対して体力値を受け取ってゲージに反映します。
次にこの関数を複製してダメージ用につなぎ替えます。
UpdateDamageValueという名前にしました。
関数を使ってゲージが減るしくみができたところで、Gateノードの登場です。
EventGraphに戻って、イベントノードの EventTickを使います。
[G]キーを押しながらクリックすると Gate ノードを取り出せます。
ダメージを受けてダメージゲージを減らすアニメーションを処理している間だけこのゲート(門)を開くという作戦です。最初は閉じておきたいので、Start Closed にチェックを入れたままにしておきます。
で、ゲートを開くのはだれか?
ということで、Open のところにカスタムイベントをつなぎます。
じゃあ閉じるのは?
ということで、Close のところにもカスタムイベントをつなぎます。
そして、このカスタムイベントを呼ぶのは体力ゲージを減らす関数です。
再び関数 UpdateVitalValueを編集します。
右端に、Set Timer by Event ノードをつなぎます。
これは指定した時間が経過したらイベントを呼ぶというノードです。
(JavaScriptの SetTimeOutメソッドみたいなものです)■Eventピンから左にドラッグして CreateEventノードを取り出します。クリエイトといいつつもプルダウンで既存のイベントを探して選択します。ここでは、さっきGateノードのOpenにつないだカスタムイベントを選択しています。Time のところに入力した値 0.5 が待ち時間です。単位は秒です。
同じようなノードに Delay があります。一定時間待つのはどちらも変わらないのですが、Delayと違って Set Timer~ は次のノードに処理がそのまま流れていくので、処理が滞らないのがありがたいのです。
ちなみに Delayノードは関数内に置くことができません。EventGraphのみです。
これで、体力ゲージが変化したタイミングで、0.5秒待ってゲートがオープンするようになりました。
EventGraphに戻ります。
Gateノードの続き、門をくぐったあとの処理をつなぎます。
ダメージ用の変数は体力ゲージと同じか下回るまで、毎回 0.01 ずつ減らします。この値が減るスピードになります。減らしたらダメージゲージ更新用の関数を呼んで反映します。EventTickノードにつながっているので、門が開いている間、常にここの処理に流れてきます。
しばらく減らしていって体力ゲージに追いついたら、ここでようやくCloseにつないだカスタムイベントを呼びます。これで門が閉じます。
次に体力ゲージが更新されるまでは処理されることはありません。
これでWidgetは完成です。
レベルブループリントで試しに表示してみましょう。
とその前にオマケを。
ブーリアンの変数をひとつ用意します。
Editable と Expose on Spawn にチェックを付けます。
初期値は一応 falseにしておきましょうか。
EventConstructの右端に下のようなノードをつないでおきます。
このブール値をチェックして反転するかしないかというものです。
Scale X にマイナスの値を入れると、左右が反転します。
では保存してレベルブループリントに移りましょう。
まずCreate Widget ノードを取り出して、できたWidgetをセットします。
さっき作ったブーリアン変数の名前が追加されています。Expose on Spawnすると初期値がここでセットできるようになるので便利です。これを複製して2個にします。
最後にAdd to Viewport をつないでいったん確認してみましょう。
どちらかのチェックボックスにチェックを付けておきます。
ゲージが左右に2つ出ればOK。
あとは適当にゲージを減らすようにイベントをつなぎます。
各CreateWidgetノードの右にある ReturnValue ピンからドラッグすると、中の関数を取り出すことができます。
Vキーを押すと強制的に 0.5 と 0.2 が入るようにしてみた。
以外に簡単にできました。
次回、体力ゲージが短くなったら点滅させる処理を追加してみます。
ではでは
素敵なゲージライフを!