第十一回ぷちコンに応募したので学んだことと反省会

# 前書き
そんなわけで、さっそくなのですがぷちコンに応募しました。
[![](https://img.youtube.com/vi/92B2T5uq2Cg/0.jpg)](https://www.youtube.com/watch?v=92B2T5uq2Cg)
その際に発生したアレコレを思い出しつつ、今後に生かすための反省会として、フランクにまとめておこうかと思います。

# ことのあらまし
ちょうどぷちコンのお題が発表されていたとき、自分はUE4極める本でUE4の学習をしていたのでした。
最初は学習中だったのでもう少し知識とかつけてからのほうがいいかなと思ったのですが、
ちょうどお題「えん」が自分がポートフォリオ的に作ってみたかったものと大体一致していたため、
「あっこれポートフォリオのたたき台としていい感じかも」
と思って、二月中に急いで極める本を完走し作り始めました。

# 作りたかったもの
まず、作りたかったものを箇条書きでまとめると、

 - 中央の的の周囲を自機が円運動で回転して、同じくその外周を円運動する敵からの攻撃を防御する
 - 敵の攻撃は的に向かって弾を発射して攻撃する
 - 敵の弾は自機が動いているときに限り、自機の前方もしくは移動の際に発生したエフェクトに当たることで消すことができ る
 - 自機を使って弾を消した場合、自機のゲージがたまり、そのゲージを利用して敵への攻撃やバリアを張ることができる
 - 一定時間防御し続けると、新しく的が発生。一部の敵がそちらの的へ移動および攻撃を始めるので、自機も複数の的を移動しながら、もしくは自機を各的に新規に配置し、守る対象を変更しながらどれくらいの時間守り切れるかをタイムアタックする

という内容でした。
まとめた結果、要素がどう見ても詰め込みすぎだったので、実際に開発するときはもう少しシンプルにルールを変更したほうがいいなと思いました。
それと同時に、自分の現状と一か月という開発期間だと全部作りこめないだろうということがどう見てもわかるので、
プランA：敵の弾を自機が円回転することで消していく。自機も敵も円回転をする。
プランB：パワーを消費して一定範囲にバリアーを張る、敵を破壊できる 等、明らかに時間がかかるであろう箇所
と二つの開発プランに分けて、プランAを今回の応募で実装するという方針で開発に入ったのでした。

# やったことあれこれ
やったこと全部書くと大変なので、自分的に印象に残った開発をいくつかまとめておきます。
### レベルに配置済みのアクタを初期値として設定する
自機および敵、弾の標的として、レベルに配置済みの的を各BPに設定したかった。
今回は回転軸となる的が一つなので、そのまま直接BPを検索して設定すればいいのですが、
今後、的となるものを複数作成した場合、そのアクタの中から適当な一つを返すようなアクタ管理系BPがほしくなり、
そのことを考えて、初期値設定用アクタを作成しました。
実装としては、
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245782/d73305b0-d13b-829b-6f55-eb44f57ae896.png" width="25%"> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245782/01c2e041-a6b7-b412-c792-0ccd309da725.png" width="30%">
このような、ひたすら変数のみを設定したBPを作成し、そこに初期値のオブジェクトを設定。
実際にこれらの変数にアクセスする場合は、逐一Getしてくるのもアレだったので、別途管理系BP取得関数を作成。
![initActor3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245782/87b236b8-c313-16e9-2a8a-1c00154b597a.png)
あとは、必要な時に応じて、この関数経由で管理BPの取得および変数から初期値の取得を行っていました。
![initActor4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245782/f01e667c-5d84-07ea-fe35-e5e4489b2d0e.png)
もしかしたらもっといい手があったのかもしれませんが、個人的にはこの方法は管理しやすかったです。
### 円運動処理
ちょうど極める本で、カメラをキャラを中心に回転させる、という処理を作成していたので、それを応用することにしました。
特に敵なんかはRotator componentがあるので、そっちで回転させたほうがよかったのかもしれないですが、
敵の移動等を実装するとなった場合、移動方向や位置計算ができるかな？と思ったり、イレギュラーな動作をしたい場合にRotator component使わないほうが制御しやすいかな？と思ったので、SetActorLocationによる移動を採用しました。
AddMovementInputの使用も考えたのだけど、当時は円回転運動の計算式まで頭が回らなかったので……
実際の処置としては、Tickが実行されるごとに、的からPawnを向きそこからさらに指定した角度に傾けたRotaterを作成し、そのRotaterを使用して移動先となる位置を作成。
![create_rotate_vector.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245782/03ea5efb-6ae9-781e-eaa7-c47e827f3195.png)
そして、その移動先をSetActorLocation(実際は向きも設定していたのでSetActorLocationAndRotation)で設定していくことで実装しました。![tick.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245782/5e849952-8733-985e-a35e-2f195791e4d8.png)
### 敵の弾の発射と移動を同時にAIで管理する
上記で、敵の回転についてもSetActorLocationで対応していこうとしたけど、敵については移動のほかに弾の発射処理も実装しなければいけません。
そのため、ビヘイビアツリーによるAI実装にしようと思いました。
Tickでもよかったのだけど、まあAIによる処理を復習もかねて押さえておきたかったので。
移動用のツリーと弾発射用のツリーをそれぞれ作ってBeginPlayの時に両方読み込めばいいのかな？と思ったら、
片方しか読み込んでくれないことが発覚したので、二つのツリーを一つのツリーに統合。
また、このときにはじめてSimpleParallelを使用。
ツリーを試行錯誤しながら、この辺りは改めてきちんと勉強したほうがいいかもなあ、と思ったのでした。
まあ、勉強になったからいいじゃないかと前向きに考えます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245782/da0ed9f9-1d49-468e-1f44-ca94c28a09b2.png" width="50%">
### UE4Hubに助けを求める
そして、上記のツリーを構築時に、プレイヤーの処理で実装した回転処理はうまく想定通りに回転はしているが、
ビヘイビアツリーでAIによる回転がうまくいかないという事故が発生しました。
原因は自分の変数の変数設定の見逃しだったわけですが。
それで、何日も修正してもうまくいかないので、UE4Hubの扉をたたいたのです。
こういう、質問系のコミュニティに書き込むことはなかったので、とても新鮮だったし緊張もしたし、
何か無礼なことを起こさないよう、すごい気を付けて詳細を書き込みました。
説明の抜けとかあったりしたら大変ですしね。
書き込みがあったときは、「UE4Hubには神がいる……！」と本気で思いましたし、
神の方々がいるので、今後ともたよりたいと思います。
### UE4のサンプルプロジェクトのアセットを素材として拝借する
最後の一週間の追い込み、「なんとかこれでプランAは提出できそうー！」というところまできたので、
後回しにしていた、各種エフェクトやマテリアル、サウンドに組み込みに着手しました。
主にフリーの素材で作成していたのですが、特にマテリアルでいい感じのがさっくりと見つからなかったので、
先に目をつけていた、UE4公式サンプルのシリージオさんのマテリアルやSE等を拝借することにしました。
しかし、シリージオさんは最新のバージョンには対応していなかったので、このままだとアセットのインポートができない……
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245782/bb653a60-3d08-a1a9-1c7f-1129f821c054.png" width="50%">
ということで、ネットで調べてみたら自分のPCに入っているバージョンで開く方法を発見したので、その方法をとることにしました。
プロジェクトファイル(*.uproject)を右クリックして「Generate Unreal Engine version...」を選択。
![copy2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245782/e7e7ee5c-3eeb-8a9e-7772-83b3b11be3e9.png)
開きたいUE4のインストール済みのバージョンを選択するボックスが現れるので、開きたいバージョン(当時は4.21)を選択。
![copy3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245782/458577e0-7d36-f014-4b03-8abdea549869.png)
これで、無事に最新のUE4でも過去のバージョンで作られたプロジェクトを開けるようになりました。
とはいえ、バージョンの切り替えにより構成等を壊したり動作不良になったら大変なので、コピーを作ってそれのバージョンを切り替えたほうがいいと思います。

# 開発を終えて(まだ終わってない)
残念ながら入賞は逃してしまいましたが、
今回は初めての応募ということで、どのように開発を進め応募するのか、現状の自分にどれだけの開発できる時間があるのか、そういったことができたような気がします。
自分ができることが広がった感じがあるので、もっといろいろなことを試してみたいし作ってみたいです。
それはそれとして、ポートフォリオのたたき台ができたという面が大きいので、応募できた時点で自分の中では100点満点です。
一回勝手を理解したのだから、次は今の積み重ね的な感じでほかのことも取り入れていきたいです。
今後のことを考えて、あとで再利用できそうなもの(回転処理とか、スタートから終了までのレベル遷移)は整理しておきたいです。

# 積み残しはありませんか？
動画を作成して投稿完了して気が付いたのですが、的となる惑星のHPが0になったときのエフェクトを入れ忘れていました。
焦っていたということもあって、忘れていたんだろうなあ。

そして、先に書いた通り、まだ入れたかったけどオミットしたゲームのルールである、プランBの数々があるわけです。
ある程度BP等を整理してから、ゆっくりとプランBの積み残しを消化していこうかと思います。
他の勉強(C++やunityとか……)もありますしね。