元UnityエンジニアがUnrealEngine 5.1から5.3に上げたときにハマったこと

## あいさつ
こんにちはNARIと申します。
これまで7年近くUnityのエンジニアをしてましたが
半年前くらいから縁があって株式会社ブラストエッジゲームズで
Unreal Engineのエンジニアとしてお仕事をしています。

2ヶ月くらい前に[デバッグ表示を簡単にするC++マクロを紹介](https://note.com/blastedge_note/n/n4aa58d6250a4)という記事を
会社で書かせてもらってます。
もう1つ執筆中なのですがちょっと執筆に苦戦中なため
今回、合間の小ネタとして書かせてもらいます！ｗ

今回は3年以上開発している「[GOMAN -stuck in the avici hell](https://store.steampowered.com/app/2112780/GOMAN_stuck_in_the_avici_hell/?l=japanese)」という
UnrealEngineのゲームでバージョンアップした際に
発生したトラブルを紹介したいと思います。

小さいトラブルですが何かの参考になればと思います。

一部UnrealEngineのGithubリンクを張ってますが以下の登録をしないと見れないので
見たい場合は登録を願いします。
https://www.unrealengine.com/ja/ue-on-github

## トラブルその1 AIが動かない
ゲーム中に出現する敵が全く攻撃しなくなる不具合が発生しました。
![2023-12-14_11h50_35 (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178782/817f00a1-e4d3-abfd-09cc-838053564403.gif)

原因はめっちゃ小さいことだったのですが特定に時間がかかりました。
確認したことは
1. 敵の生成・初期化周りの確認
2. 敵のビヘイビアツリーの挙動確認

で進めました。
1については処理をみてみても全く問題ありませんでした。
2はすぐに異常が見つかりました。
挙動としては、ノードの動きが全く違う動きをしており
ノード判定の処理に問題があることがわかりました。
ここからが大変でノードの条件分岐をエンジンのどこでやってるか
特定が大変でした。

ビヘイビアツリー上でブレークポイントを貼れますが
エンジンとは切り離して動いているためソースコードから見つけないといけません。

エディタ上で表示されてる設定項目の名前を全体検索かけて
エディタ処理を見つけたらランタイムとして動かしてる処理をそこからさらに探して
該当の処理を特定しました。
[該当のGit上のコード](https://github.com/EpicGames/UnrealEngine/blob/072300df18a94f18077ca20a14224b5d99fee872/Engine/Source/Runtime/AIModule/Private/BehaviorTree/Blackboard/BlackboardKeyType_String.cpp#L55)

文章にすると簡単ですがUnrealEngineは大きいプロジェクトだったので
中々処理がどれと紐づいてるか見て回るだけでも苦労しました💦
該当のコード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178782/f2d2d6e1-8ed7-3d29-c836-bd7dcffc8e2b.png)


上記の処理は分岐Nodeで設定した文字列とBlackBoardにある変数の値を比較して判定する処理になります。
今回この比較が(Emptyの文字列).Contains(BlackBoardの変数)のような形で受け取っていました。
そして今までは同じ条件でFalseを返していたものがTrueを返すようになっていました。

つまりFStringの挙動が変わったことが原因でした。
(Emptyの文字列).Contains("")のようなケースだと
今までTrueだった動きがFalseを返すようになりました。
Containsの処理を見てみると確かにそうしたコメントが書かれています。
`Returns whether the string contains the substring. If the substring is empty, returns true.`
コミットメッセージを見てみると
`and match the behavior of standard library strstr`
とあるのでstrstrライブラリに挙動を合わせたため修正されたようです。
[該当のGit上の修正](https://github.com/EpicGames/UnrealEngine/commit/f8cec4755604e5dbec2cecc5158a7b8e449662ea)


Containsの挙動テスト
5.1でFALSEを返していたのが5.3でTRUEを返すようになっている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178782/3f18285a-fd89-9450-e971-f1bbecdf8f7f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178782/54613117-e557-400c-898d-0a685098252f.png)

なのでこの修正は永続的なものなので使用している箇所の処理を直す必要があります。
最終的にビヘイビアツリーの分岐処理をEqualで判定する形に直して対処しました。
本当はフラグ管理などで対応する予定でしたが依存している箇所が多く特定が難しい不具合などが発生したためこの対応で進めました。

修正差分
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178782/0bd70e36-03d4-d3cb-4453-420597a43f17.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178782/3fcb0b38-fdca-60d9-9bcd-395a198f2590.png)

一応補足しておくと今回の不具合は
Emptyの文字列にEmptyでCointainするようなケースで発生するだけなので
今回、ビヘイビアツリーの使い方で起こった不具合なのですが
基本的にはIsEmpty使えばいいのでほとんど影響がない不具合です。

## トラブルその2 敵が出現しない
普段出現するはずの敵が一部出現しなくなっていました。
このポイントから出現する敵が出現しなくなっている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178782/2059a4a1-7ed3-8368-47ac-70c120154eb1.png)

出現処理が問題あると仮説を立ててステップ実行して調査していきました。
その結果、衝突判定される粒度が変わっていることがわかりました。

IssueTrackerから同じような事象を見つけて
原因と経緯を特定することができました。

こちらは元々不具合があった挙動が修正されたため発生したようでした。
今回の不具合と再現手順などは違いますが
関係するコードが修正されてるためこのあたりが原因と判断しました。
不具合修正のため今後もこのままの実装の可能性が高いため
対策としてプロジェクト側のオブジェクトの配置を変更して対処しました。
[該当のIssue](https://issues.unrealengine.com/issue/UE-153368)

衝突時判定されるオブジェクトが5.1と5.3で変わっている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178782/5ef2f241-60e6-d5e6-d892-e4d6ff02f5ca.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178782/89630fdc-f6ab-3a6c-48cf-f538de9f938f.png)

敵の生成失敗時はエラーダイアログを出してる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178782/8ccef340-f15a-b53f-eee7-6cc4a9d00954.png)

## トラブルその3 UIが消えない
これは該当のBPを調査してすぐに原因が特定できました。
原因は初期化処理が2回走っていたためでした。
GameplayCueNotifyのOnActiveが2回呼ばれいていた。
そのためUIを生成する処理が2重に走ってしまい参照から外れた消えないUIが出ていました。

画像のような感じで操作案内のボタンが残り続けていた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178782/3d60e8da-8f46-4e4e-e14e-1b0aeb254450.png)


最終的にIssueTrackerから同じような事象を見つけて
原因を特定することができました。
こちらは修正待ちのステータスだったので2回処理が走っても良い修正をして対処しました。
UI変数のチェックをする処理を入れた感じですね。
[該当のIssue](https://issues.unrealengine.com/issue/UE-191936)

修正後のBP
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178782/69906a36-f429-b38b-bd65-4532974f9feb.png)

## 換装した感想
いやなんかダジャレ言いたくて換装って言っただけですが
バージョンアップした感想ですね。

Unityのバージョンアップも経験してますが
大きな違いとしては、修正経緯が探しやすいです。
エンジン側のソースコードにブレークポイント貼ったりステップ実行できるので
不具合部分の特定が非常にわかりやすいです。

Unityだとこのあたりどうしても再現環境を作って問い合わせとなるので
場合によっては問い合わせ用の環境を用意できず泣き寝入りみたいになったりもします。

原因が分かれば[IssueTracker](https://issues.unrealengine.com/)で検索もできて便利です。
再現手順や報告されたフォーラムなどもわかりソースコードの修正コミットと紐づいて
状況が管理されるため原因の特定が非常にやりやすいです。

Unityも同じ様に[IssueTracker](https://issuetracker.unity3d.com/)があります。
こちらも再現手順や報告されたフォーラムなどがわかるため非常に参考になりますが
ソースコードと事象が紐づいて報告されるわけではないので
仮説止まりで終わることもあります。

また、エンジン自体のプロジェクト状況がGithubで見れるのもとても良いですね。
[Githubのプロジェクト参加が必要](https://www.unrealengine.com/ja/ue-on-github)ですがとても簡単なので登録をおすすめします。

コミットの履歴でどうしてそうした修正をしたかもわかるので
IssueやReleaseNoteに載ってない修正も確認することができます。
修正意図がわかれば今後修正されそうなものなのかや誤ったコードなのかなども
判断できるためとても作業が進めやすかったです。

もちろんUnityも[ソースコードを公開](https://github.com/Unity-Technologies/UnityCsReference)してますが修正経緯がわかるような形ではないため
こうしたアップデートの作業では、活用が難しいです。

改めてUnrealEngineはエンジン更新の際は、参考にできる情報が多く
とてもやりやすかったです。

もちろんUnityも優れているところはあります。
ネット上に情報が多く遭遇した不具合なども対処している記事を後から探しやすいですし
メインバージョンごとのサポートが長いため
アップデート検証に時間をかけて取り組みやすい形になっています。

逆にUnrealEngineはLTSのような1つのバージョンをサポートする体制ではなく
大きなアップデートに合わせて修正を行うスタンスのため
そうした点では、Unityのほうがやりやすいことがあると思います。

それぞれバージョン移行にあたって特徴があるため合わせた運用をするのがベストですね。

## 宣伝
今回の記事で対応したゲームタイトルは
株式会社ブラストエッジゲームズで開発している「[GOMAN -stuck in the avici hell](https://store.steampowered.com/app/2112780/GOMAN_stuck_in_the_avici_hell/?l=japanese)」という
3Dの横スクロールアクションゲームになります。

規模としましては10名以下の少人数で開発している
オリジナルタイトルのインディーゲームになります。

来年にアーリーアクセスを予定してますのでリリースされたら是非遊んで見てください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178782/31ba84b5-18b6-c6e4-90f1-f580055157aa.png)

また、一緒に開発してくれる方も絶賛募集中なので
会社へのエントリーもお待ちしてます！
https://www.blastedge-games.co.jp/recruit
一緒にUnreal Engineでゲームを作りましょう！

以上になります。