[UE4] シングルパックファイル内のアセットリストを取得する

検証バージョン:UE4.26
# 背景
　ゲームを開発する際にテクスチャ、マップ、アニメーションなど様々なアセットが登場しますが、ゲームで使用するアセットを1つのかたまりにまとめておくことがあります。例えば、ステージ(マップ)のアセットにはオブジェクトやエフェクトなどの配置物がありますが、それらはレベルとメッシュやパーティクルから構成されます。このように1つアセットに紐づくようなケースや、1つのグループとして管理したい場合には「チャンク」というものを利用します。エディタ上ではあまり意識することはありませんが、実際にゲームをダウンロードする場合などにはチャンク単位で分けておくと様々な面で有利です。この詳細については以下のドキュメントにもあります。

[[公式ドキュメント] クック処理とチャンク化](https://docs.unrealengine.com/4.26/ja/SharingAndReleasing/Patching/GeneralPatching/CookingAndChunking/)

　もう少し分かりやすく図示したものが以下の図です。例えば「ダウンロードコンテンツとして新しいステージを追加したい」ような場合においては、追加するステージに紐づくアセットをチャンクで1まとまりにしておくとよいです。

![2021-06-18_02h00_47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101019/76fe9ab0-61a4-1df8-4591-9f9b57a710a7.png)

　チャンクはPrimaryAssetLabelを使用して管理し、設定した内容がどのようにチャンク毎に格納されるかはEditorのAssetAuditを使用しても確認することができます。以下の図ではチャンクID毎にPrimaryAssetLabelとマップがきちんと分離されていることを確認できます。
![2021-06-18_01h45_35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101019/0ffef6ce-28e6-9c36-24f5-8a592ca343ce.png)

　そしてPrimaryAssetLabelでどのアセットがどのチャンクになるかを指定していたら、チャンク毎に.pakファイルという1つの塊ファイルが作成されます。ShooterGameのサンプルは最初からPrimaryAssetLabelが設定してあるので、プロジェクト設定でGenerateChunksを有効にしてパッケージを作成すると、チャンク毎に.pakファイルが作成されます。

![2021-06-18_02h15_39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101019/412b06d7-e031-7c03-0a83-f2aa3f50a8ad.png)

チャンクに設定したアセットは.pakファイルになりますが、パッケージの以下の工程で作成されます。
[[UE4] ビルドプロセスの流れ](https://qiita.com/donbutsu17/items/f798d159049f82a277ee) の内容を参照。

![2021-06-18_02h13_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101019/515394a2-9dbe-7843-8f61-48406da88c01.png)

# チャンク毎にきちんと格納されている？
　何も特別な設定をしていなければPrimaryAssetLabelで設定したチャンクIDに従ってアセットは.pakファイルに格納されますが、PrimaryAssetLabelでの設定が正しくなかったり、以下の内容のようなパッケージまでの過程において.pakファイルに含めたいアセットを追加したり除外できるので、結局のところ作成された.pakの中身を見てみないことには正確な状態はわかりません。

[[UE4] アセットの追加/除外する設定と機能](https://qiita.com/donbutsu17/items/d910d22d6ed3867e3d43)

# シングルパックファイルのアセットを確認
そこで正しくチャンク毎にアセットが格納されているかを調べる方法を以下に示します。これを利用することによって、.pakファイルに格納されているアセット一覧を出力して、想定されたアセットが想定されたチャンクに含まれているかを確認することができます。

## .pakファイル使用時 (IOStore=OFF)
以下の内容をバッチファイルにして環境ごとに併せた内容に編集することで、格納されたアセットリストを.csvとして出力できます。

```batchfile:IOStore有効時[.pakファイル用]
rem @ UnrealPak.exe のパス
set UNREALPAK_PATH=D:\Release-4.26\Engine\Binaries\Win64\UnrealPak.exe
rem @ .pak のパス
set PAK_PATH=D:\MyProject\Saved\StagedBuilds\WindowsNoEditor\MyProject\Content\Paks\MyProject-WindowsNoEditor.pak
rem @ アセットリストの出力先
set CSV_PATH=D:\Batch\List\MyProject-pak.csv

%UNREALPAK_PATH% %PAK_PATH% -list -csv=%CSV_PATH%
```
出力された結果は以下のように出力されます。
![2021-06-18_01h24_17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101019/9284fb55-915f-fa4b-53f5-b758ee6296a1.png)

## .utocファイル使用時 (IOStore=ON)
UE4.25から入ったIOStoreの機能を利用する場合はアセットを格納する先が変わるので、異なる方法で確認します。
やり方は殆ど同じですが、以下の内容をバッチファイルにして環境に併せて内容に編集しアセットリストを.csvとして出力できます。

```batchfile:IOStore有効時[.utocファイル用]
rem @ UE4Editor-Cmd.exe のパス
set CMDEXE_PATH=D:\Release-4.26\Engine\Binaries\Win64\UE4Editor-Cmd.exe
rem @ .utoc のパス
set UTOC_PATH=D:\MyProject\Saved\StagedBuilds\WindowsNoEditor\MyProject\Content\Paks\MyProject-WindowsNoEditor.utoc
rem @ アセットリストの出力先
set CSV_PATH=D:\Batch\List\MyProject-utoc.csv

%CMDEXE_PATH% -run=IOStore -list=%UTOC_PATH% -csv=%CSV_PATH%
```
出力された結果は以下のように出力されます。
![2021-06-18_01h30_58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101019/7b64c7ad-8bcf-1a3b-7caf-53609cce0c8b.png)

# 注意点
このような方法でアセットリストが取得できるのですが、通常は.pakを暗号化してからリリースするので解析できないようになっています。そのため暗号化済の.pakファイルは出力しようとしてもクラッシュして見れないようになっています。逆に.pakファイルは暗号化することが必須です。

# .csvファイルが出力されない時
暗号化されている、.pakまでのパスが異なる、エンジンバージョンが異なるなど、上記のコマンドが失敗するケースは様々あります。もしそのような場合はコマンドプロンプトからバッチファイルを実行したり、バッチファイル実行時にpauseを追加して、出力されるコールスタックを確認してみましょう。