LoginSignup
3
2

More than 3 years have passed since last update.

UE4 Commandletでアセットを一括修正してみる

Last updated at Posted at 2020-06-06

概要

UnrealEngine での コマンドレット(Command-Line Applet)についてのメモです。
アセット変更をコマンドレットを使って行ってみます。

▼関連
UE4 アセットを一括修正してみる #EditorUtilityWidgetを使っています。
UE4 CommandletでBPを変更してみる

環境

Windows10
Visual Studio 2017
UnrealEngine 4.24

参考

以下を参考にさせて頂きました、ありがとうございます。

[UE4] コマンドレットを使って、コマンドラインに任意の処理を実装する
UnrealC++で画像ファイルからテクスチャアセットを作成する
C++からCommandletを実行する方法
UnrealEngine : UCommandlet
UnrealEngine : Commandlets

コマンドレット(Command-Line Applet)について

コンソールアプリのことで、GUIエディタを起動させずに実行することができます。

"Engine\Source\Runtime\Engine\Classes\Commandlets\Commandlet.h"

コマンドレットは、ゲームが読み込まれていない、クライアントコードが読み込まれていない、レベルが読み込まれていない、アクターが存在しない "生の"環境で実行されます。

作成例

2Dテクスチャアセットを探し出して特定のパラメータを書き換えをして保存するコマンドレットの作成例です。

MyCommandlet.h
#pragma once

#include "CoreMinimal.h"
#include "Commandlets/Commandlet.h"
#include "MyCommandlet.generated.h"

// テクスチャパラメータを書き換えるコマンドレット
UCLASS()
class TEST_API UMyCommandlet : public UCommandlet
{
    GENERATED_BODY()

public:
    UMyCommandlet(const FObjectInitializer& ObjectInitializer);

    virtual int32 Main(const FString& CmdLineParams) override;

    // 対象アセットリストを取得する
    void GetAssetList(TArray<FAssetData>& _AssetList) const;
    // アセット書き換え
    bool ChangeAsset(FAssetData&    _AssetData, float _ChangeParam);

};
MyCommandlet.cpp
#include "MyCommandlet.h"
#include "AssetRegistryModule.h"
#include "AssetRegistryHelpers.h"
#include "Editor/LevelEditor/Public/LevelEditor.h"
#include "FileHelpers.h"
#include "Misc/FileHelper.h"

DEFINE_LOG_CATEGORY_STATIC(LogMyCommandlet, Log, All);

// コンストラクタ
UMyCommandlet::UMyCommandlet(const FObjectInitializer& ObjectInitializer)
    : Super(ObjectInitializer)
{
    LogToConsole = false;
}

// メイン
int32 UMyCommandlet::Main(const FString& CmdLineParams)
{
    TArray<FAssetData>  _AssetList;
    TArray<UPackage*>   _PackagesToSave;

    // アセットリストの取得
    GetAssetList(_AssetList);

    // 引数パース
    FString _Value;
    if (FParse::Value(*CmdLineParams, TEXT("param="), _Value))
    {
        // パラメータ値を引き数から取得
        float _Param = FCString::Atof(*_Value);

        // アセット変更
        for(auto _AssetData : _AssetList){
            // パラメータ変更
            if( ChangeAsset(_AssetData, _Param) ){
                // 変更したパッケージ追加
                _PackagesToSave.Add(_AssetData.GetPackage());
            }
        }

        // アセットセーブ
        for(const auto& _It : _PackagesToSave){
            // ファイル名
            const auto _FileName = FString::Printf(TEXT("../../../test_app/Content/%s%s"), *_It->GetFullName().RightChop(14), *FPackageName::GetAssetPackageExtension());

            // パッケージ保存
            bool _Ret = UPackage::SavePackage(_It, nullptr, EObjectFlags::RF_Public | EObjectFlags::RF_Standalone, *_FileName);
        }

        return(0);
    }

    // エラー終了
    return(1);
}

// 対象アセットリストを取得する
void UMyCommandlet::GetAssetList(TArray<FAssetData>& _AssetList) const
{
    FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>(FName("AssetRegistry"));
    IAssetRegistry& AssetRegistry = AssetRegistryModule.Get();

    IFileManager& _FileMgr = IFileManager::Get();


    // 対象ディレクトリを探す
    FARFilter Filter;
    Filter.bRecursivePaths = true;
    // 対象パス(Contentフォルダ全体を対象にするなら "/Game/" を指定)
    Filter.PackagePaths.Add(TEXT("/Game/"));

    // 対象クラス指定
    Filter.ClassNames.Add(UTexture2D::StaticClass()->GetFName());

    AssetRegistry.GetAssets(Filter, _AssetList);

}

// アセット書き換え
bool UMyCommandlet::ChangeAsset(FAssetData& _AssetData, float _ChangeParam)
{
#if WITH_EDITORONLY_DATA
    if (UTexture2D* _Texture = Cast<UTexture2D>(_AssetData.GetAsset())){
        // 変更する
        _Texture->AdjustRGBCurve = _ChangeParam;

        // 編集フラグ設定
        _Texture->MarkPackageDirty();

        return(true);
    }
#endif  
    return(false);
}


実行

-runで指定するコマンドレット名は Commandlet を省略できます。
UMyCommandletクラスの場合、MyMyCommandlet のいずれかで指定ができます。
-param でパラメータ値を指定するようにしています。

\Engine\Binaries\Win64\UE4Editor-Cmd.exe {PROJECT_PATH}/MyProject.uproject -run=My -param=2.0 -stdout -UTF8Output

まとめ

コマンドレットを使うとエディタを起動せずに任意の処理を適用できます。コマンドレットの記事があまり見当たらないためエンジン付属コマンドレットすら大して使えていないです、どなたか有用な使い方を教えて下さい。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2