johnnyGameStudio’s blog

無能なゲームプログラマのぼやき ぎーくになりたい Twitter: https://twitter.com/JGS_Developer

【UE4】CommandletでTextureのSizeなどのMeta情報を取得出来ない場合の解決策とその原因

開発環境

UE4.26.2 Windows10 Visual Studio 2019

はじめに

この記事の内容はとてもシンプルだが、いざCommandletでAssetの詳細データを取得しようとすると上手くいかず、解決策を探すのに手間取ったので備忘録として記録する
おそらく同じような同士がいると思うので誰かの助けになれば幸い

発生した現象

参考先(※1)を元に以下のようなCommandletを追加し

int32 UMyCommandlet::Main(const FString& CmdLineParams)
{
    TArray<FAssetData>  _AssetList;
    GetAssetList(_AssetList);

    for (auto Asset : _AssetList)
    {
        if (UTexture2D* TmpTexture = Cast<UTexture2D>(Asset.GetAsset())) {
            
            UE_LOG(LogSandbox, Log, TEXT("Texture Size x:%d y:%d"), TmpTexture->GetSizeX(), TmpTexture->GetSizeY());
        }
    }

    return(1);
}

そして※1を参考に以下のコマンドで実行してみる

{EnginePath}\Engine\Binaries\Win64\UE4Editor-Cmd.exe {Pj Path}Sandbox.uproject -run=My -param=2.0 -stdout -UTF8Output
pause

実行した際のLogである"\Saved\Logs{PJ Name}.log"を開いてみると以下のように、テクスチャサイズが取れないことがわかる

[2022.03.21-21.51.02:162][  0]LogSandbox: Texture Size x:0 y:0
[2022.03.21-21.51.02:163][  0]LogSandbox: Texture Size x:0 y:0
[2022.03.21-21.51.02:165][  0]LogSandbox: Texture Size x:0 y:0
[2022.03.21-21.51.02:167][  0]LogSandbox: Texture Size x:0 y:0
[2022.03.21-21.51.02:168][  0]LogSandbox: Texture Size x:0 y:0
[2022.03.21-21.51.02:170][  0]LogSandbox: Texture Size x:0 y:0
...

発生原因

GetSizeXの中身を確認するとEngineのソースでは以下のようになっており、このPlatformDataがNullであることがわかる

 FORCEINLINE int32 GetSizeX() const
    {
        if (PlatformData)
        {
            return PlatformData->SizeX;
        }
        return 0;
    }

PlatformDataの生成場所

ではなぜNullか?通常のエディタ実行時ではこのPlatformDataが生成されるのはどこなのかをブレイクポイントで追ってみると以下の処理順でCallされるCreateTransient関数内で生成されることが分かった

UThumbnailManager::SetupCheckerboardTexture > FImageUtils::CreateCheckerboardTexture > UTexture2D::CreateTransient

Commandletではサムネイルを必要としないのでこのままでは生成する大本であるUThumbnailManagerがCallされず、各テクスチャのPlatformDataも生成されないことがわかった

解決方法

Commandlet実行時に引数「-allowcommandletrendering」を追加する 以上

補足

解決策はとてもシンプル
ヒストリア様の参考リンク(※2)ではデフォルトで記述されているのでそのままコピペして使っていると気づかないが、このallowcommandletrenderingはあらゆるレンダリング系の情報を取得する際に必須になる引数なので常につけておいて良いことがわかった

動作確認

前述したコマンドの最後に引数として「-allowcommandletrendering」を追加して実行してみると、以下のLogのようにテクスチャサイズが取得できることが分かった

{EnginePath}\Engine\Binaries\Win64\UE4Editor-Cmd.exe {Pj Path}Sandbox.uproject -run=My -param=2.0 -stdout -UTF8Output -allowcommandletrendering
pause
[2022.03.21-21.54.13:272][  0]LogSandbox: Texture Size x:2048 y:2048
[2022.03.21-21.54.14:390][  0]LogTexture: Display: テクスチャをビルドしています:T_Brick_Clay_Beveled_M (AutoDXT、2048X2048)
[2022.03.21-21.54.14:390][  0]LogSandbox: Texture Size x:2048 y:2048
[2022.03.21-21.54.14:616][  0]LogTexture: Display: テクスチャをビルドしています:T_Brick_Clay_Beveled_N (BC5、2048X2048)
[2022.03.21-21.54.14:616][  0]LogSandbox: Texture Size x:2048 y:2048
[2022.03.21-21.54.15:732][  0]LogTexture: Display: テクスチャをビルドしています:T_Brick_Clay_New_D (AutoDXT、2048X2048)

参考リンク

(※1) https://qiita.com/unknown_ds/items/e49aa05e142a04a1ee59
(※2) https://historia.co.jp/archives/7343/