道具で頭をつぶす
すでにボーンスケールで遊んでいるので、このチュートリアルではさらに一歩進めて、キャラクターの頭を平らにつぶしてみましょう!
私……平らになったと言えるかも。
最初の試み
まずは慣れ親しんだ、定番のOn Keystroke PressedノードとThrow Prop At Characterノードから始めましょう。(もちろんOn Keystroke Pressedは好きなイベントノードに置き換えられますが、ここでは簡単にするためそのまま使います。)Throw Prop At Character → From を Above Character Head に、距離を5に設定していることに注目してください。これにより、道具はキャラクターの頭上から落下します。

前回のチュートリアルで行ったように、道具がキャラクターに衝突したときに Set Character Bone Scale ノードを使って頭のボーンをスケーリングできます。

これでCを押すと、道具がキャラクターの頭上から落下し、衝突時にキャラクターの頭が平らにつぶれます。
頭のボーンを元のスケールに戻すための、別の Set Character Bone Scale ノードも追加しましょう。

頭のボーンスケールをリセットしたいときは いつでも、Enterフロー入力をクリックできます! (お好みならホットキーを割り当てることもできます。)これは、以下のセクションで頭のスケールをリセットしたいときにとても役立ちます。
Multi Gate
ここまでで、キャラクターの頭を平らにつぶす方法と、それをリセットする方法がわかりました。問題は、Cを押す回数が増えるほど頭がもっと平らにつぶれる、という進行を持たせたいことです。どうすればよいでしょう?
Multi Gate ノードが役に立ちます! これまで見てきたノードとは異なり、Multi Gateノードには可変数のフロー出力があります。つまり、必要なだけフロー出力を持たせられます。以下のように Exit Count を4に設定すると、Exit 1からExit 4までの4つのフロー出力が表示されます。

Multi Gateがトリガーされるたび、次のフロー出力 をトリガーします。たとえば、最初にトリガーされたときはExit 1、2回目はExit 2がトリガーされます。Multi Gateが5回目にトリガーされたときはExit 5が存在しないため、再びExit 1がトリガーされ、サイクルが繰り返されます。
まさに必要なものです! Multi Gateが最初にトリガーされたときは頭のボーンスケールを1にリセットし、2回目には少しつぶし、3回目にはさらに少しつぶす、といったことができます。ブループリン トにすると、次のようになります。

通常のスケール(1, 1, 1)から始まり、少しつぶした(1.33, 0.83, 1.33)、さらに(1.66, 0.67, 1.66)、そして(2, 0.5, 2)となります。X軸とZ軸は拡大し、Y軸は縮小していることに注目してください。これにより頭が平らにつぶれます。XとZを1のままにしてYだけを縮小することもできますが、この方法でつぶしたほうが見た目がよいと私は思います。
ではCを数回押してみましょう。4回ごとにリセットされながら、頭がどんどん平らにつぶれていくはずです!
変数
ここで終わりにしてもよいのですが、もっと面白くしたくなりますよね。頭を10回つぶしたい場合は? 100回なら? フロー出力100個とSet Character Bone Scaleノード100個を作るのはよい考えではありません。もっとよい方法があるはずです。
そこで 変数 が役立ちます。変数は、ノードによって変更・読み取りできるデータの一部です。上のブループリントでは4つのSet Character Bone Scaleノードを作りましたが、各ノードの設定は Scale オプション以外は本質的に同じです。つまり、たくさんのノードを作る代わりに、ノードを1つだけ作り、そのノードに変化する値(つまり変数)をスケールとして使わせることができます!
まず変数を作成しましょう。ノードエディターの Properties タブへ移動 し、+ ボタンをクリックして変数を作成します。名前を BumpedTimes、型を Integer に設定します(Integer(整数)とは小数部分を持たない数のことで、頭を1.5回や2.3回つぶすことはできないためです)。

Throw Prop At Characterノードの直後に Integer Variable Add ノードを使い、道具がキャラクターに衝突するたびに変数を1ずつ増やします。

Warudoに戻ってCを数回押してみましょう。道具がキャラクターに衝突するたびに、変数が1ずつ増えるはずです。

この変数を読み取るには、Get Integer Variable ノードを使います。Propertiesタブで BumpedTimes 変数を0にリセットし、以下のようにSet Character Bone Scale、Get Integer Variable、Scale Vector3ノードを追加しましょう。Scale Vector3 → Scale は(1, 1, 1)に設定されています。

続きを読む前に、このブループリントが何をするか推測できますか?
ここでCを押すと、道具がキャラクターに衝突するたびに頭のボーンがどんどん大きくなるはずです! これは理にかなっています。道具が当たるたびにBumpedTimesを1増やし、その後、頭のボーンスケールをBumpedTimes倍した(1, 1, 1)に設定しているからです。つまり、最初に道具が当たったとき、BumpedTimesは1で、頭のボーンスケールは(1, 1, 1) × 1 = (1, 1, 1)です。2回目に当たったとき、BumpedTimesは2で、頭のボーンスケールは(1, 1, 1) × 2 = (2, 2, 2)です。以下同様です。
しかし、頭を風船のように大きくしたいのではなく、つぶしたいのです! 以下のブループリントを再現してみましょう。

PropertiesタブでBumpedTimes変数を0にリセットし、Cを数回押します。頭のボーンがどんどん平らにつぶれるはずです! しかし、これはどのように動くのでしょうか?
このようなブループリントを読むときに私が使う小さなコツは、データの流れを右から左へ追うことです。この場合、Set Character Bone Scaleノードへ最終スケールを出力する Vector3 リテラルノードから始 めます。XとZの値は上側の Float Addition ノードから、Yの値は下側のFloat Additionノードから渡されていることに注目してください。上側の Get Integer Variable → Float Multiplication → Float Addition パスは本質的に(BumpedTimes × 0.1 + 1)を計算し、下側のパスは(BumpedTimes × -0.1 + 1)を計算しています。
最終結果が整数(integer)ではなく小数(float)であるため、Integer Multiplication/AdditionノードではなくFloat Multiplication/Additionノードを使っています。
BumpedTimesの値ごとに、最終スケールを手で計算してみましょう。
| BumpedTimes | XとZ | Y | 最終スケール |
|---|---|---|---|
| 1 | 1 × 0.1 + 1 = 1.1 | 1 × -0.1 + 1 = 0.9 | (1.1, 0.9, 1.1) |
| 2 | 2 × 0.1 + 1 = 1.2 | 2 × -0.1 + 1 = 0.8 | (1.2, 0.8, 1.2) |
| 3 | 3 × 0.1 + 1 = 1.3 | 3 × -0.1 + 1 = 0.7 | (1.3, 0.7, 1.3) |
| 4 | 4 × 0.1 + 1 = 1.4 | 4 × -0.1 + 1 = 0.6 | (1.4, 0.6, 1.4) |
ここにパターンが見えているはずです。XとZの値は毎回0.1ずつ増え、Yの値は毎回0.1ずつ減っています。これはまさに望みどおりです。道具が当たるたびに、頭のボーンはどんどん平らにつぶれます!
変数をリセットする
ただし、Cをさらに数回押すと、やがて頭のボーンが逆方向に伸びるのがわかります。

なぜでしょう? 先ほどの計算を続けてみましょう。
| BumpedTimes | XとZ | Y | 最終スケール |
|---|---|---|---|
| 8 | 8 × 0.1 + 1 = 1.8 | 8 × -0.1 + 1 = 0.2 | (1.8, 0.2, 1.8) |
| 9 | 9 × 0.1 + 1 = 1.9 | 9 × -0.1 + 1 = 0.1 | (1.9, 0.1, 1.9) |
| 10 | 10 × 0.1 + 1 = 2 | 10 × -0.1 + 1 = 0 | (2, 0, 2) |
| 11 | 11 × 0.1 + 1 = 2.1 | 11 × -0.1 + 1 = -0.1 | (2.1, -0.1, 2.1) |
| 12 | 12 × 0.1 + 1 = 2.2 | 12 × -0.1 + 1 = -0.2 | (2.2, -0.2, 2.2) |
Yの値が負になっています。これは頭のボーンが下方向に伸びることを意味します! これは望みどおりではありません。BumpedTimesが10のときに頭のボーンスケールを(1, 1, 1)へリセットしましょう。頭が下方向に伸びずに得られる、最も平らな状態だからです。幸い、ダンスチュートリアルで学んだIf Branchノードを使う方法をすでに知っています!

新たに追加したノードはとてもシンプルです。BumpedTimesが10以上かを確認し、そうであれば0にリセットして、頭のボーンスケールも1に戻します。
ここでは Integer Greater Than Or Equal ノードを使っていますが、Integer Equal ノードを使ってBumpedTimesが10と等しいか確認することもできます。違いは、前者はBumpedTimesが10、11、12などのときにIf Trueフロー出力をトリガーする一方、後者はBumpedTimesがちょうど10のときにのみIf Trueフロー出力をトリガーすることです。私たちは通常、より柔軟な前者を使います(何らかのミスでBumpedTimesが11になったとすると、0へリセットできなくなってしまいます)。
完成したブループリントは次のようになります(かなり大きいですね!)。

おめでとうございます! これがブループリント変数です。これは以前のものより難しいチュートリアルなので、ここまでたどり着いたことに拍手です!