フェイザー砲制御 with UE5

# 概要
某SFシリーズファンメイド自主制作プロジェクトの内部実装紹介その2にして原点
フェイザー砲(ビーム砲)のエフェクトをNiagaraで作ったまでは良かったものの、シーケンサーでNiagaraを制御するにはLife Cycleトラックは癖があり少々厄介。というわけでBP内で動的に制御してしまおうという試み。

# 基本要件

- ターゲットとの位置関係により発射位置をフェイザーアレイ(船体表面のレール状構造)に沿って移動させる。
    (レール上かつターゲットとの最短距離を取りたい)
- 発射時のエネルギー収束とビームエフェクト本体との同期。
![StarTrekMini - Unreal Editor 2024_06_28 11_16_16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752748/becca095-c758-28df-f6e8-f79d2508a546.png)


# エフェクト部分
### ビームエフェクト本体
- Ribbonに自前のマテリアルを適用
- Absolute Beam Start/EndをユーザーパラメーターとしてBPと連携
![NS_PhaserStrip2 2024_06_28 11_14_42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752748/cebfaf0b-b709-9be2-1898-766aba6bcc92.png)

### エネルギー収束エフェクト
- レール部分のUVを直線的に展開し、マテリアル側で移動可能なグラデーション処理を組み、UV両端から収束地点に移動させる

![PhaserStrip 2024_06_28 11_12_48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752748/3969a369-7447-f5fe-72c4-80f7df4c5769.png)

- グラデーションと収束位置をDynamic Material ParameterとしてNiagaraに制御権を渡し、BP側での演算結果をパラメーターとしてNiagaraに渡す
全景
![M_PhaserStrip 2024_06_28 11_17_33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752748/87815a85-3f7a-0d91-22d7-75b0af0c27fe.png)
グラデーション部分(片側)
![PhaserStrip 2024_06_28 11_14_00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752748/e1c7133f-3282-ecd1-3189-bd74781815b3.png)
マテリアルパラメーターの制御
![NS_PhaserStrip2 2024_06_28 12_54_33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752748/930a5a27-14a0-b25f-ec13-ec0eb010201a.png)



# 最終的なアプローチ
紆余曲折を経て、最終的な処理方法は次のようになった。

- レール状複数地点の座標(アクターのローカル座標)、収束地点のUV座標、余計なレールのUVをマスクするためのUV座標をカスタム構造体の変数に格納する
![StarTrekMini - Unreal Editor 2024_06_28 12_33_29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752748/2d9aeb03-954e-5da9-9134-2659c185363c.png)

- この位置リストに合わせて角度による条件分岐を設定
    こちらも角度の上限と下限を格納する構造体の配列に格納する
![StarTrekMini - Unreal Editor 2024_06_28 12_39_57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752748/3f82dd15-c250-53f6-85d2-56f761165032.png)



```mermaid
graph LR;
    A[位置関係算出]-->B[配列参照して発射・収束位置決定]-->c[エネルギー収束（0.7s）]-->D[ビーム発射（1.0s）];
```
- ↑これを1サイクルとして射程内にターゲットが存在する間繰り返す
- サイクルの管理はSet Timer by Eventで行うことに

BPでの実装はこの画像のようになった
![StarTrekMini - Unreal Editor 2024_06_28 12_27_50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752748/a6afa2e4-9ffa-3bba-75a1-e70c4275b891.png)
順番に見ていくと...

1. ターゲットが射程内に入った/出たときにサイクルを開始/停止する
![StarTrekMini - Unreal Editor 2024_06_28 12_28_33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752748/43f6bc20-2c8a-aab5-e22b-c6e42964e162.png)
2. 上方、下方、後方からターゲットの相対位置を特定する
![イベントグラフ 2024_06_28 12_29_08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752748/cbe6151e-e552-ef08-7dfd-7f4055e06799.png)


3. どの角度帯にあるかを判定し、該当するエフェクトの緒言を参照する
![イベントグラフ 2024_06_28 12_29_08trim.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752748/f8c698a4-3aff-ed64-fa19-976e5a16ac7f.png)

実際に動作する様子はこちら
![phaserdemo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752748/0d926a5c-5478-3a8a-e368-bbc4e184ff57.gif)


# 終わりに
この処理方法を導き出す過程でBP内におけるベクトルと座標系の取り回しやマテリアルグラフでのmathノードの扱い方を学ぶことができ、その後の制作にかなり活かすことができた。
（あわよくば将来的にはレールに沿ってリアルタイムで発射位置を移動させたりしてみたいところ...）