［UE5］スマブラのファイアボールのような弾を発射する

# 概要
この記事では、Unreal Engine 5 で、下の動画のような、スマブラのマリオのファイアボールのような挙動をする弾を、プレイヤーから発射できるようにします。

<iframe width="640" height="360" src="https://www.youtube.com/embed/5zE8T42kg8Q" title="fireball 7" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

具体的には、下の5つの条件を満たした弾を発射できるようにします。

1. 床に当たると跳ねる
1. どのような高さから落としても一定の高さまで上がる
1. XY軸方向には、どのような斜面に当たっても等速度で移動する
1. 壁に当たると消える
1. 一定時間経過すると消える


# この記事の主な対象者
- Blueprint（BP）の作り方の基礎を習得されている、初心者の方


# 1. 床に当たると跳ねる弾をスポーンできるようにする

最初に、弾として使用するアクタのBPを作成します。

下図のようなコンポーネント構成のBPを作成します。

![fireball_components.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/debe6929-7a7b-d67e-4684-f4f5a8f2dafc.jpeg)

|コンポーネント名|コンポーネントの種類|備考|
|:-:|:-:|:--|
| StaticMesh | Static Mesh | **このコンポーネントを一番上の親にします。**<br>メッシュには「Sphere」を用います。 |
| ProjectileMovement | Projectile Movement | 弾の動きを制御するために使用します。 |

「StaticMesh」コンポーネントを、一番上の親にしている理由は、一番上にしないと「ProjecttileMovement」コンポーネントの影響により、弾が床や壁をすり抜けるようになってしまうからです。<br><br>


上のコンポーネントを作成し終えたら、次に弾の動きを制御する「ProjectileMovement」コンポーネントの設定を行っていきます。

最初に、「ProjectileMovement」コンポーネントの詳細パネルを開きます。

詳細パネルの「プロジェクタイルバウンス」＞「Should Bounce」（下図の赤枠）にチェックを入れます。「プロジェクタイルバウンス」＞「Should Bounce」にチェックを入れることで、弾が跳ねるようになります。

![shouldbounce.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/5dc08044-664b-9e9b-7f1a-c0721cb04a35.jpeg)<br><br>


次に、詳細パネルの「プロジェクタイル」＞「Projectile Gravity Scale」を調整し、弾の重さを調整します。今回の記事では Projectile Movement コンポーネントの機能を利用して、弾の動きを制御するのですが、Projectile Movement コンポーネントでは弾の重さを直接設定する項目がありません。

そのため、代わりに弾にかかる重力を大きくし、弾の重さが大きくなるようにします。（今回の記事では、「プロジェクタイル」＞「Projectile Gravity Scale」の値を「2.5」にします。）

![projectgravityscale.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/542659b3-28d2-b94a-04de-705fd5db38bf.jpeg)

これで、「ProjectileMovement」コンポーネントの設定は完了です。<br><br>


「ProjectileMovement」コンポーネントの設定を終えたら、プレイヤーの前に作成した弾をスポーンできるようにしていきます。

最初に、プレイヤーのBPを開き、カプセルコンポーネントの下に Scene コンポーネント「ProjectileLocation」を作成します（下図の赤枠）。

「ProjectileLocation」コンポーネントの位置、向きに、弾をスポーンするので、「ProjectileLocation」コンポーネントの位置はプレイヤーの少し前、「ProjectileLocation」コンポーネントのX軸の向きは、プレイヤーの前方向になるようにします。

![projectilelocation2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/34aab94e-07eb-f3bd-8c00-3544c2cbd5ea.jpeg)<br><br>


次に、プレイヤーのBPのイベントグラフを開き、下図のノードを組みます。
下図のノードでは、マウスの右ボタンを押したときに、上で作成した弾を「ProjectileMovement」コンポーネントの位置、向きにスポーンするようにしています。また、スポーンする際に、弾のスケールを調整しています。（今回の記事では、0.4 倍にしています。）

![spawnfireball.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/31e4f360-cd68-821e-7b23-13aea68c0dae.jpeg)<br><br>

これで、プレイヤーの前に作成した弾をスポーンできるようになったはずなので、ゲームプレイし、下の動画のようになっているか確認します。

<iframe width="640" height="360" src="https://www.youtube.com/embed/GB97y4ez2rU" title="fireball 2" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>


# 2. どのような高さから弾を落としても、弾が一定の高さまで上がるようにする

次は、どのような高さから弾を落としても、弾が一定の高さまで上がるようにしていきます。

下図の動画の状態が、この節の処理を実装する前の状態です。

<iframe width="640" height="360" src="https://www.youtube.com/embed/6FaVu1_oOW4" title="fireball 3" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

この節の処理を実装すると、下の動画のようになります。

<iframe width="640" height="360" src="https://www.youtube.com/embed/0MxdLbNmnb8" title="fireball 4" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

上の動画では、弾が床で跳ねる瞬間に、Z軸の速度を設定した特定の値に変更するようにして、弾が床で跳ねた後に一定の高さまで上がるようにしています。

これから、そのような処理を実装していきます。<br><br>


最初に、上で作成した弾のBPのイベントグラフを開きます。

次に、弾が床で跳ねる瞬間に設定する、弾のZ軸の速度を設定するための変数を作成します。（今回の記事では、変数名を「ProjectileVelocityZ」にし、デフォルト値を「800」にします。）

![projectilevelocityz.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/acd2ae67-ba93-0583-d063-e728672487c0.jpeg)<br><br>


最後に、下図のノードを組みます。
下図のノードでは、弾がどこかに当たったときに、Z軸方向の弾の速度を、設定した速度になるようにしています。

![constantheight_before.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/1bf451cd-020a-3a97-193a-343deef79d0e.jpeg)<br><br>


これで、どのような高さから弾を落としても、弾が一定の高さまで上がるようになっているはずなので、ゲームをプレイし、下の動画のようになっているか確認します。

<iframe width="640" height="360" src="https://www.youtube.com/embed/0MxdLbNmnb8" title="fireball 4" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>


# 3. XY軸方向には、どのような斜面に当たっても等速度で移動する

次は、弾のXY軸方向の速度がどのような斜面に当たっても不変であり、等速度で移動するようにします。

最初に、上で作成した弾のBPのイベントグラフを開きます。

次に、弾を発射した際の、XY軸の弾の速さを設定するための変数を作成します。（今回の記事では、変数名を「ProjectileSpeedXY」にし、デフォルト値を「500」にします。）

![projectilespeedxy.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/4bbe688c-36f6-842e-f07f-fa9ace048fb5.jpeg)<br><br>


次に、下図のノードを組みます。
下図のノードでは、弾がスポーンされたときに、スポーンされた弾の向きに、設定した速度で弾が発射されるようにしています。

![beginplay_velocity.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/3e1ccb97-1c1f-15c5-4eea-a799ed998f90.jpeg)<br><br>


最後に、弾が一定の高さまで上がるようにするために作成したノードを、下図のように組み替えます。
弾の速度のXY軸方向においては、弾が床に当たったときの速度をそのまま利用するようにする処理を加えます。

![constantheight.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/512bdf4f-87c4-0412-b520-665f8927634d.jpeg)<br><br>


これで、弾のXY軸方向の速度が常に一定の速度になるようになっているはずなので、ゲームをプレイし、下の動画のようになっているか確認します。

<iframe width="640" height="360" src="https://www.youtube.com/embed/6fkUVchOw14" title="fireball 5" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>


# 4. 弾が壁に当たったときに弾が消えるようにする

次に、弾が壁に当たったときに、弾が消えるようにしていきます。

弾のBPのイベントグラフを開き、下図のように「On Projectile Bounce」ノードを組み替えます。
下図のノードでは、壁となる場所の法線のZ軸方向が 0 に近い値となることを利用して、弾が当たった場所が壁かどうかを確認して、弾が当たった場所が壁だったら弾を削除するようにしています。
（下図のノード「On Projectile Bounce」の「Impact Result」構造体は、構造体ピンに分割した表示にしています。）

![destroyprojectile_onhitwall.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/2625f389-e985-fc63-8903-7670c82e44c5.jpeg)<br><br>


上図のノードを組み終わったら、ゲームをプレイし、下の動画のようになっているか確認します。

<iframe width="640" height="360" src="https://www.youtube.com/embed/-25ozGiH0r8" title="fireball 6" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>



# 5. 一定時間経過すると消えるようにする

最後に、弾を発射してから一定時間が経過したら、自動で消えるようにしていきます。

弾のBPのイベントグラフを開き、「BeginPlay」のノードの末尾に、下図の赤枠の部分のノードを加えます。
下図の緑枠のところに、自動で消えるまでの時間を設定します。

![destroyprojectile_passtime.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/ff9eda84-8579-7381-57c6-7d6a61f82ce4.jpeg)<br><br>


これで完成です。ゲームをプレイし、下の動画のようになっているか確認します。

<iframe width="640" height="360" src="https://www.youtube.com/embed/qNc1rILAduM" title="fireball 1" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
<br><br><br>



以上で今回の記事の内容は終了です。
最後まで読んでいただき、ありがとうございました。