【UE5】パッケージでObjectSerializationErrorのFatalErrorが発生する場合はBuildCookRunの-nocompileeditorが原因かも

# 概要
パッケージのexe起動後直ぐに↓のSerializeのFatalErrorが発生することがあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29542/a68107f5-4a38-4cc3-9ef4-bbc68a3cd2c8.png)

```
Fatal error: [File:D:\build\++UE5\Sync\Engine\Source\Runtime\CoreUObject\Private\Serialization\AsyncLoading2.cpp] [Line: 2042] 
ObjectSerializationError: /Game/Blueprints/BP_TestGameMode (0x337255296EC6AFBB) /Game/Blueprints/BP_TestGameMode (0x337255296EC6AFBB) - BP_TestGameMode_C /Game/Blueprints/BP_TestGameMode.Default__BP_TestGameMode_C: Bad import index 572662306/14.
````

これが発生している場合はパッケージの生成が上手くできていません。
原因を調査したので備忘録として残しておきます。

■環境
- Windows 11
- UnrealEngine 5.5.4

# まとめ

- CookはEditorのdllを使って行われる
    - Editorのdllはエンジン/プロジェクト/プラグインのものが存在する
    - プロジェクトのEditorのdllは `プロジェクトのルート/Binaries/Win64/UnrealEditor-プロジェクト名.dll` に生成される
- CookされたBPに存在しないはずのデータが入っている等の不整合があるとパッケージ起動時に Serialize の FatalError が発生する
    - **古いEditorのdllでCookが行われると BP に存在しないはずのデータが入ってしまう等の不整合が発生してしまう**
- **BuildCookRunのオプションに-nocompileeditorを付けているのが原因の可能性が高い**
    - -nocompileeditor のオプションが付いている場合はパッケージ作成時にEditorのdllの最新のソースコードでのビルドが行われず、Editorのdllが更新されない
        - 古いEditorのdllのままになる
    - **Jenkins等のエディタを起動しない環境でBuildCookRunを動かす場合は-nocompileeditorのオプションを外しておくのが良さそう**

# 検証
## 検証用プロジェクトについて
検証のために↓のプロジェクトを用意いたいました。

https://github.com/ogamita777/TestNoCompileEditor

プロジェクト名は TestNoCompileEditor です。
ローカルPCでは d:\work\TestNoCompileEditor がプロジェクトのルートフォルダになっております。

正常にゲームが起動すると、↓のようなマップで一人称視点で動くプレイヤーが生成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29542/d01ed997-6225-4f67-b38f-5a8125804dcb.png)

BuildCookRunは下記のような感じで行います。ビルド構成(-clientconfig)はDevelopmentです。
```bat
"C:\Program Files\Epic Games\UE_5.5\Engine\Build\BatchFiles\RunUAT.bat" ^
BuildCookRun ^
-project=%PROJECT_PATH% ^
-noP4 ^
-platform=Win64 ^
-clientconfig=Development ^
-cook ^
-allmap ^
-build ^
-stage ^
-pak ^
-partialgc
```
(※参考：[［UE4］AutomationToolを使ってみる](https://zenn.dev/kihoku/articles/ad7be2c491cd34))

各種ファイルに関する説明は下記です。
|ファイル|説明|備考|
|---|---|---|
|Content\Map\TestMap.umap|検証で使うレベルです||
|Source\TestNoCompileEditor\Private\GameMode\TestGameModeBase.h|BP_TestGameModeの基底クラスです。`UPROPERTY(EditDefaultsOnly)`な `int32 Hoge;`プロパティがあります![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29542/1d008816-a4d8-4cd2-a1a8-ddea3dde98e7.png)||
|Content\Blueprints\BP_TestGameMode.uasset|TestMapで設定されているGameModeです。Hogeプロパティの値をデフォルトの0から100に変更します![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29542/dceebada-bd4e-47c5-9989-2816d0dc432c.png)||
|Tool\Editor\MakePackage.bat|BuildCookRunで **-nocompileeditorを付けず** にパッケージを作成します|Editorのdllが**更新されます**。Saved\StagedBuilds\Windows にパッケージが作成されます|
|Tool\Editor\MakePackage_**NoCompileEditor**.bat|BuildCookRunで **-nocompileeditorを付けて** にパッケージを作成します|Editorのdllが**更新されません**。Saved\StagedBuilds\Windows にパッケージが作成されます|
|Tool\Editor\Launch_Stage_Standalone.bat|パッケージをStandaloneで起動します|Saved\StagedBuilds\Windows のパッケージを起動します|

## SerializeのFatalError を発生させる
MakePackage.bat を実行
↓
UnrealEditor-TestNoCompileEditor.dllが作成され、Cookが行われ、Saved\StagedBuilds\Windowsに パッケージが作成されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29542/3529b4c2-4da0-4e71-a766-3398f89ddc7e.png)
↓
Launch_Stage_Standalone.bat を実行してパッケージ(exe)を起動します。特に問題なく起動します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29542/0a6f8486-3168-4ef2-86d9-2b26cf384e19.png)
↓
ATestGameModeBaseのHogeプロパティをコメントアウトします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29542/0bd94ea8-d91f-4db0-b5c3-a799734462e5.png)
↓
MakePackage_**NoEditorCompile**.bat を実行
↓
UnrealEditor-TestNoCompileEditor.dllの**更新が行われず**(↓のスクショの通りタイムスタンプが前のMakePackage.batで生成されたときの23:03のまま)、Cookが行われ、Saved\StagedBuilds\Windowsに パッケージが作成されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29542/c513010b-3e0f-4ac5-9e72-698f6f7ff51f.png)
↓
Launch_Stage_Standalone.bat を実行してパッケージ(exe)を起動します。**BP_TestGameModeのSerializeでのFatalError**が発生します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29542/179526a5-1ed2-48e2-961a-5d759fd0368b.png)

Editorのdllを更新せずにCookを行ったため、BP_TestGameModeに本来存在しないはずのHogeが残ったままになり、Serializeでの不整合が起きていることが確認できました。

## 一回もエディタビルドを行わずに -nocompileeditorを付けてパッケージを作成すると？

Binariesフォルダを削除してプロジェクトのEditorのdllを削除し、一回もエディタビルドが行われていない状態にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29542/35f42c22-ff4d-42c6-9d09-299a326cc9eb.png)
↓
MakePackage_**NoEditorCompile**.bat を実行
↓
ビルドまでは成功するのですが、**Cookの開始直後に失敗**します。
下記のようにTestNoCompileEditorEditor.targetが無いと出ます。
```
System.IO.FileNotFoundException: Could not find file 'D:\work\TestNoCompileEditor\Binaries\Win64\TestNoCompileEditorEditor.target'.
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29542/f4e9b8c8-6691-4e38-8a80-3be5667869b1.png)

Cookを行うためにはBPが属しているEditorのdllのパスを取得する必要があるのだと思われます。
TestNoCompileEditorEditor.targetにパスが記載されており、パスを取得しようとしてファイルを開こうとするのですが、エディタビルドが一回も行われていないとTestNoCompileEditorEditor.targetは生成されず、ファイルが存在しないので失敗しているようです。
↓
試しに、Binaries\Win64フォルダに TestNoCompileEditorEditor.targetだけ追加して、MakePackage_**NoEditorCompile**.batを実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29542/781a2fad-c714-46fa-9fd0-755946a668e4.png)
↓
今度はCookの開始直後ではなく、ある程度進んでから失敗しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29542/fcfbee64-176f-402a-a2b5-d20375c32c4e.png)

Error_UnknownCookFailureと出力されており、失敗した正確な原因がこれだと良くわかりません。

より詳細なログが出力されている 
`C:\Users\%UserName%\AppData\Roaming\Unreal Engine\AutomationTool\Logs\C+Program+Files+Epic+Games+UE_5.5\Cook-*.txt`を確認します。
TestNoCompileEditorが見つからないから失敗しているというログが出力されておりました。
```
Message dialog closed, result: Ok, title: Message, text: The game module 'TestNoCompileEditor' could not be found. Please ensure that this module exists and that it is compiled.
```

# 参考文献
- [[UE4] 4.9におけるパッケージングまとめ ～ProjectLauncher & Console編～｜株式会社ヒストリア](https://historia.co.jp/archives/3684/)
- [［UE4］AutomationToolを使ってみる](https://zenn.dev/kihoku/articles/ad7be2c491cd34)