ロッ○マンX風な自作ゲーム『ユニティちゃん＆グレイちゃん』体験版を仕事をしながら２ヶ月で作る　その2：基礎ロジックを作る（チャージ処理）

[Unreal Engine 4 (UE4) Advent Calendar 2018](https://qiita.com/advent-calendar/2018/ue4)　2日目の記事、続きです。

２０１８年夏コミで制作したロッ○マンX風な自作ゲーム『ユニティちゃん＆グレイちゃん』の体験版をどのように作っていったか書いていきたいと思います。
前回は[「その１：マケプレに廃課金」](https://qiita.com/YuukiOgino/items/bc3c2364a8ca57d65ca0)になります。

今回は基礎ロジック、チャージ処理の仕組みを書いていきます。

※現在も残りを書いています。遅くなって申し訳ございません。
※関数、変数名が色々とまとまりがなく、わかりにくいです。短期間で実装していた影響であることをご理解ください。
※全部を解説するのは時間が足りないため、Blueprintである程度作り方を把握している人向けに書いています。

#チャージ処理

チャージ処理のロジックを作成していきます。

基本的な仕様は以下に定めています。よほどの理由ができない限り、このゲームではこの部分を変えるつもりはありません。

1. 攻撃ボタンを押す→低威力の弾を発射
2. 低威力の弾を発射後、攻撃ボタンを押しっぱなし→チャージ開始（時間計測）
3. チャージ開始後、攻撃ボタンを離す→チャージした時間に応じて中～高威力の弾を発射
    1. チャージ1段階→中威力の弾を発射
    2. チャージ2段階→高威力の弾を発射
    3. チャージ3段階→高威力の弾、その後２回、チャージ無しで高威力の弾を発射(ストックチャージ)
        1.  ストックチャージ最後の弾は、地形貫通の超高威力の弾を発射
        
以下、上記仕様を満たしたGIFです。

・通常ショット～チャージ１段階
![shot.gif](https://qiita-image-store.s3.amazonaws.com/0/104377/a9e37388-064f-30e4-8848-cc3e3b0112f8.gif)

・チャージ２段階
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">チャージショット２段階目 <a href="https://t.co/dWVptWoB5o">pic.twitter.com/dWVptWoB5o</a></p>&mdash; 荻野雄季 (@YuukiOgino) <a href="https://twitter.com/YuukiOgino/status/1084548684786720768?ref_src=twsrc%5Etfw">2019年1月13日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

・チャージ３段階→ストックチャージ
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">いまQiitaの記事書き中。Qiitaのほうだと10MB以上のGIFあげられないのでTwitter経由でアップ<br>チャージショット３段階目 <a href="https://t.co/vsnx1zz7EF">pic.twitter.com/vsnx1zz7EF</a></p>&mdash; 荻野雄季 (@YuukiOgino) <a href="https://twitter.com/YuukiOgino/status/1084548572656234496?ref_src=twsrc%5Etfw">2019年1月13日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

###Input設定

まず、InputのActionMappingsに「Shot」と名付けた攻撃ボタンアクションを登録します。
![action.png](https://qiita-image-store.s3.amazonaws.com/0/104377/7fc55255-33aa-dcfd-87b2-0daed2381481.png)

※Inputの場所「プロジェクト設定→エンジン→インプット」（日本語の場合）

##Blueprint実装

つづいてBlueprintでチャージショットの仕組みを実装していきます。
使用しているのは主にタイムラインになります。

以下の通り、Characterを継承したBlueprintでの実装を前提にしています。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/104377/8d649dc0-bd4f-ef77-d783-b63ae8919abf.png)

変数の設定は以下の通りです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/104377/726fa87c-fbf4-5a59-bd46-63b4e7939d41.png)

・ChageAttackNum：チャージショットの段階を格納する変数
・StockChageNum：ストックしたチャージショットの数を格納する変数

### InputAction「Shot」

まず、Input設定で入力したshotのインプットアクションを実装します。
![attack1.png](https://qiita-image-store.s3.amazonaws.com/0/104377/61941468-dc8e-6a46-d7f7-88a227c5902b.png)

・Pressed処理

shotに設定したボタンを押したときに、自作した通常攻撃のEvent（ShotActionEvent、後述）を経由して、攻撃アニメーション再生、および弾のBlueprintを生成しています。
Delayノードで少し処理を止めて、**IsInputKyeDownノード**でshotで受け取った構造体「Kye」からボタンを押していることをチェックし、trueだったら自作したチャージショットのEvent(StartChageEvent：後述)を呼びます

・Released処理

ボタンを離したとき、自作したチャージ処理終了イベント（EndChageEvent、後述）を呼び出して**チャージに関係するタイムラインを全て止めます**。

その後、ChageAttackNumを値を見て、0であれば自作したチャージショット攻撃イベント（ChageActionEvent、後述）を呼び出して、ChageAttackNumの値をもとにした弾のBlueprintを生成しています。
ChageAttackNumが0でない場合、自作したストックチャージ用のイベント（StockAttackEvent、後述）を呼び出して、ストックに応じた弾のBlueprintを生成しています。

### カスタムイベント「ShotActionEvent」「ChageActionEvent」

通常攻撃、およびチャージショット攻撃のカスタムイベントを作成します。

![attack2.png](https://qiita-image-store.s3.amazonaws.com/0/104377/0264ac1b-a6d1-bc47-04fc-be211b1127e7.png)

ここでは攻撃処理の関数（AttackShot、ChageAttackShot、後述）と攻撃終了処理の関数（EndAttackShot）を呼び出しています。

### カスタムイベント「StartChageEvent」「EndChageEvent」

今回の**メイン**です。チャージに関するカスタムイベントを以下のように作成します。

![attack5.png](https://qiita-image-store.s3.amazonaws.com/0/104377/207a54e0-a1c9-668c-e4f7-bcbed2d58aeb.png)

今思えば改善点がありますが、体験版の時点ではタイムラインでチャージの時間を計測しています。
大体、以下のような感じでタイムラインを作成しています。

・ChageTimeLine（１段階～２段階の測定：Finishiedが呼ばれた段階で２段階と判定）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/104377/8196b7fc-cf7d-dec7-beae-ec7c7ced7c71.png)

・SecondChageTimeLine（３段階への測定：Finishiedが呼ばれた段階で３段階と判定）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/104377/798b041b-da96-df0c-9ebd-c936df53f4a2.png)

チャージしていることをプレイヤーに知らせるためのSE再生、パーティクルエフェクト再生が混じっていますが、やりたいことは、**チャージが何段階目なのかをChageAttackNumに設定**、**チャージの最終段階になったらChageAttackNumに加えてStockChageNumに設定する**、ということです。

この部分が出来れば、チャージ処理ができると思います。

### カスタムイベント「StockAttackEvent」「ResetChageEvent」

チャージの３段階目、ストックチャージショット専用のカスタムイベントです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/104377/8f915b09-5b67-c5b8-dd27-30e222a10f6f.png)

「UnCranchCapsuleComponent」という関数がありますが、最後のストックチャージの攻撃時に前転を解除するものであるため、今回は説明しません。
※書き終わったらリンクを貼る予定です。

### 関数「AttackShot」

通常攻撃を行う関数です。
![attack3.png](https://qiita-image-store.s3.amazonaws.com/0/104377/d8b18efb-cb5e-9bdc-335d-98abfe42afe6.png)

攻撃アニメーション再生をアニメーションBPに通知、およびSEの再生を行っています。
また、手に武器（銃）を持っていない場合があるため、AttachToComponentで銃を手に持たせるようにしています。

### 関数「ChageAttackShot」

チャージショット攻撃を行う関数です。
![attack4.png](https://qiita-image-store.s3.amazonaws.com/0/104377/479cb471-5705-5090-6d5b-594a17d661be.png)

攻撃アニメーション再生をアニメーションBPに通知、およびSEの再生を行っています。基本的な処理は「AttackShot」と同じになるので、不要と判断すれば将来的にここら辺をリファクタリングすると思います。
また、ストックチャージの最後には、刀を振るアニメーションで弾のBlueprintを生成する仕様のため、刀のAttach等の処理を行っています。

チャージ処理に関する部分は以上の通りになります。

#まとめ
チャージ処理を一通り書きました。説明不足な部分もありますが、タイムラインの仕組みを理解できれば実装はできると思います。

・攻撃ボタンを押す→低威力の弾を発射→押しっぱなしであれば、タイムラインを使ってチャージ処理開始
・攻撃ボタンを離す→チャージした時間によって発射する弾が変わる

他のノードもありますが、処理として最低限必要なのは上記の通りです。

弾、および攻撃アニメーションを次回記載します。
おそらく、最低あと10回このような記事が続きます。