第18回ぷちコンビルドデータ提出振り返り

# はじめに 

ぷちコンで提出した作品のビルドデータ提出が必要になりパッケージ化の対応を行ったので、その作業の過程で得られた気付きなどを書き留めていきたいと思います。
パッケージ化対応した作品の動画は以下になります。

https://www.youtube.com/watch?v=upTCoFHfmwk

## 何はともあれパッケージ化

パッケージ化はUE4でもやったことがあったので、そこまで難しいものではないと思っていました。
以下の記事を見ればほぼ完了の認識でいました。

https://docs.unrealengine.com/4.27/ja/Basics/Projects/Packaging/

https://qiita.com/O_Y_G/items/8bc60efe54f9aefafd38

が、いきなり躓きました。UE4では存在したはずのパッケージ化の項目がメニューにありません。
もう1つの記事によると、メニューの場所が変わっているようです。

https://metatimecg.com/ue5-package/

メニューの場所が変わると全然見つけられないですね。ちなみに、パッケージ化のメニューは以下の場所にあります。
![20221002_UE5でのパッケージ作成項目.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165865/162bb8ee-b861-ff67-5154-da5902de9b6a.png)
Windowsのパッケージ作成には.NET Core 3.1ランタイムも必要です。これは、VisualStudioインストーラーからインストール可能です。
![20221002_ここでランタイムを指定しないとダメか.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165865/35358ea7-d8cb-b6f9-fca6-7ee4a5f85ef8.png)
C++のビルドのために.NET Core 3.1ランタイムを別途インストールしていましたが、VisualStudioインストーラーからインストールしないと、パッケージ化では認識してくれないようです。

## すんなりとパッケージ化できた？

と、思ったのも束の間。動作確認しているとある機能が動きませんでした。
放水とゲージ回復にGameplayCueを使用しているのですが、パッケージ化するとなぜか動作しません。
検索して探してみると、原因と思える書き込みがありました。質問内容は英語でしたが、ざっくりと読むと、「アセットディレクトリをクックに追加する必要がある」とのこと。

https://www.reddit.com/r/unrealengine/comments/6ldfpl/package_gameplay_abilities_cue_system_not_working/

プロジェクト設定のパッケージ化にそれっぽい設定があったので、以下の設定をチェックすると、エディターで実行した時と同じように動作しました。
![20221009_GameplayCueがパッケージ時に有効にするための設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165865/8f12f884-6170-9b5c-a673-b9e391da477c.png)
細かくディレクトリ指定をすると良いのかもしれませんが、意図した通りに動いたので、ここはこれで良しとしました。
これから先のバグの修正などを考えると、ここだけに力を割いているわけにもいかないので。

## 応募時には見送っていたバグの対応

提出したビルドデータは、イベントなどでのプレイアブル出展の可能性もあるので、応募の際に見送っていたバグを放置するわけにもいきません。程度にもよりますが、出来る限り何とかしたいです。

### バグその1「炎の煙が出ない」

スクショだけではわかりにくいのですが、エディターを開いた直後、Niagaraエフェクトの炎の煙が出ませんでした。
Niagaraのエディターを開くと、普通に煙が出ています。
<img width="320" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165865/e470b222-a05a-71c8-33a1-ca6184b45d88.png"><img width="320" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165865/b8e9acbc-185f-9b08-92e6-fcc5ce383093.png">
その状態でエディターのビューを見ると、煙が普通に出るようになります。
<img width="320" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165865/2108deeb-b8dd-d949-9d48-fec4d803b886.png">
パッケージ化すれば解消すると思いましたがそんなことも無く、ただただ絶望するのみでした。メインのビジュアルなので、さすがにこのままでは提出も難しいので途方に暮れていました。

原因も分からず、調べても何も出てこないので、最終手段「パラメータを1つずつON/OFFする」という地道な方法で調査。結果的に、ScaleColorが原因と判明しました。

今までScaleColorを使っていてこのような現象が出たことも無いため謎です。
パラメータの扱いが間違っているなら、Niagaraのエディターを開くことで現象が消えることも無いはずなので、尚更分かりません。

結局、煙が消える際の演出の補助として使っていたパラメータで外してもほとんど影響は無いので、ScaleColorを外すことで対応完了としました。

### バグその2「外れる鎖」

プレイヤー機にぶら下がっている鎖ですが、機能別サンプルに丁度良いものがあったので使わせていただきました。物理の設定がしてあるため、直感的な動きが実現できて、イメージしていたものにぴったりでした。
![20221017_機能別サンプルから.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165865/669512da-81aa-8ecd-4e48-0ae442c740b2.png)
概ねうまく動作するのですが、ある状態においては、鎖が外れてしまうという困った現象が発生しました。物理の荒ぶりなどで扱いが難しくなることは想定していましたが、外れてしまうのは全くの想定外。
<img width="320" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165865/b6be1df4-cccf-d65e-dc6f-bc526efa2adc.png"><img width="320" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165865/ed2b847f-2ddb-91a5-8103-517e989ef1ad.png">
作業を続ける中で、動きが止まってしばらく経った状態で鎖が外れることが分かりました。そうなると、プレイヤー機が静止して物理の挙動が安定した後と推測できます。
そこで、物理が収束しないよう常に力を加えるという対応を追加してみました。
![20221017_最終手段.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165865/2b3453d8-205e-3fc1-e250-8dd032311204.png)
これで良いかはわかりませんが、現象が100%確認できていた箇所での再現は無くなりました。とりあえずは何とかなったようです。

## 色々落ち着いたところでPCを変えての動作確認

パッケージ化されたものに不足が無いか、サブのPCで念のため確認してみました。
UE4やUE5が入っている環境なので、できれば諸々がインストールされていない環境が望ましいですが、デモ展示はヒストリアさんに対応いただけるので気にしないことにしました。

有難いことに、ここでも問題が発生しました。
実際にプレイを開始してみたところ、想定よりも処理が重かったです。

昔のグラボではありますが、凝った絵作りはしていないので、それなりに軽く動くと思っていたので少し焦りました。
UE4でパッケージ化した時はそこまで重くならなかった経験があったので、UE5との違いを考えてみると、Lumenが頭に浮かびました。試しにLumenを切ってみると軽くなりました。

体感できるくらいに処理が軽くなったので確認としては終了ですが、twitterにタイムリーな情報が流れてきていたので、どれくらいの処理負荷があったのか、具体的に数値を見てみました。

https://twitter.com/pafuhana1213/status/1579767741959245824

同じ画面でプロファイリングを比較してみました。左がLumen有り、右が無しのものです。
<img width="320" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165865/a4b49225-c7b4-d8d2-a18b-2783e04ee127.png"><img width="320" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165865/fb90bd34-4ec1-9bc0-a4fb-f705fb63b641.png">
<img width="320" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165865/086155c2-3262-2ed6-54b5-9f3419f89ddb.png"><img width="320" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165865/209b3de3-0267-cd66-3edf-fcac331b4bf7.png">
数値の大きな違いがGPUで、Lumenがある場合は8～9msほど増加しているのが分かります。オープニング部分は30fps再生なので、約30msで問題無いのですが、ステージ開始時のLumen有りの場合は約20msで、60fpsの16.7msを超えているため、想定よりも処理が落ちてることが分かりました。感覚ではなくきちんと数値で分かるのは最高です。

比較すると明確に分かりますが、Lumenがある場合、オープニングでのプレイヤー機の馴染み方が凄く良い感じです。ステージ中はそこまで大きく気になる差でも無かったので、最終的にはLumenを切っての運用になっています。

Lumenを使わないのにUE5を使用する意味はあるのか？と思いもしましたが、UE5でのこれからの運用方法の模索として考えれば有りです。むしろ、こういう機会に試さないと損です。
また、古いバージョンはいずれサポートから外れるので、特に理由が無ければ、新しい環境を使っていくのが良いと思います。

## 追加要素

バグの修正に加えて、展示を意識した以下の機能追加も行いました。

- デモ
- スコアランキング
- ポーズメニュー
- 操作練習 

デモではプレイヤー機の動きを再現するため、Take Recorderを使用しています。
使用方法は公式の説明が参考になります。

https://docs.unrealengine.com/4.26/ja/AnimatingObjects/Sequencer/Workflow/TakeRecorder/UsingTR/

対象としてPlayerを指定できるのでプレイ中の動きをそのまま保存することできますが、ボタン操作やActor内のカメラ位置の保存はできないようです。しかし、このゲームでは動きが再現できれば、目的(要救助者を救出して運ぶ)を伝えることができるため、デモに使うことができました。

デモの進行としてはこれで十分なのですが、Player Actorのカメラをそのまま使用すると、プレイ中の動きとは別物になってしまう問題がありました。そこはデモ用のカメラActorを用意して、再生されたプレイヤー機を追随させて、ゲーム中の見た目に近づくようにしています。

乱数のシードを管理していないので、プレイするたびに微妙に変わる部分が出ますが、全く同じ状態を再現する必要性も無いし、恐らくそこまでデモが見られることも無いはずなので、これは放置しています。

他は普通に作れる箇所なので問題は無かったのですが、ポーズメニューを作る際に、アニメーション終了イベントが来なくなることをいつも失念してしまいます。
一瞬何が起こったか分からなくなりますが、こちらの情報を思い出せば難なく解決。

https://twitter.com/seiko_dev/status/1445369342187556869?s=20&t=a7qnA3MbnK5PtA2KgfkKOA

## 浮動小数点の丸めの違いが地味に効く

内部で浮動小数を使っている箇所は丸めの対応方法を予め決めておきましょう。
Unreal Engineに限った話ではないですが、切り上げるのか、切り捨てか、四捨五入かの扱いを、ゲーム全体、または目的の数値の算出に対して統一しないと、後々面倒な対応に追われることになります。
小数点以下の桁数なども統一しておいた方が良いです。

## まとめ

- バグ修正や気になる点の調査を通じて、学ぶことが結構あったので、解決していないことがあったら、積極的に調べるようにしたい
- 制作時とは違った視点で見れるので、パッケージ化して動かすくらいはやっておくようにしたい

## 謝辞

参加賞目当てでぷちコンに参加して丁度2年目、かつ、UNREAL FESTのオフライン開催再開という凄いタイミングで最優秀賞をいただくことができました。
敷居が低く参加しやすい、かつ、勉強になる素敵なコンテストを開催していただいたヒストリア様と、審査や解説動画などでいつもお世話になっているEpicの方々に感謝です。
何かやる度に新たな発見や学びがあり、とても勉強になります。今後もぷちコンへの参加を通じて、学びにつなげていきたいと思います。