UE4自动打包工具编写
阅读原文时间:2023年07月10日阅读:1

在UE的开发中,有些项目需要针对不同版本出不同的包,并有一个对应的GUI界面,供大家使用。

1.插件编写

先使用UE4自己的插件模板创建插件,做成插件形式

然后注册Slate UI,编写打开逻辑。并在按钮点击函数PluginButtonClicked内触发。

.cpp部分代码如下:

#include "PackageHelper.h"
#include "PackageHelperStyle.h"
#include "PackageHelperCommands.h"
#include "Misc/MessageDialog.h"
#include "ToolMenus.h"

#include "GameMapsSettings.h"
#include "Misc/FileHelper.h"
#include "FileHelpers.h"

static const FName PackageHelperTabName("PackageHelper");

#define LOCTEXT_NAMESPACE "FPackageHelperModule"

TSharedRef FPackageHelperModule::WindowBody(const FSpawnTabArgs& SpawnTabArgs)
{
return SNew(SDockTab)
.TabRole(ETabRole::NomadTab)
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
[
SNew(SButton)
.Content()
[
SNew(STextBlock)
.Justification(ETextJustify::Center)
.Text(LOCTEXT("Build Test Package1", "Build Test Package1"))
]
.OnClicked_Lambda([this]()
{
//Clicked Test Package1.

                return FReply::Handled();  
            })  
        \]  
        + SVerticalBox::Slot()  
        \[  
            SNew(SButton)  
            .Content()  
            \[  
                SNew(STextBlock)  
                .Justification(ETextJustify::Center)  
                .Text(LOCTEXT("Build Test Package2", "Build Test Package2"))  
            \]  
            .OnClicked\_Lambda(\[this\]()  
            {  
                //Clicked Test Package2.

                return FReply::Handled();  
            })  
        \]  
        + SVerticalBox::Slot()  
        \[  
            SNew(SButton)  
            .Content()  
            \[  
                SNew(STextBlock)  
                .Justification(ETextJustify::Center)  
                .Text(LOCTEXT("Build Test Package3", "Build Test Package3"))  
            \]  
            .OnClicked\_Lambda(\[this\]()  
            {  
                //Clicked Test Package3.

                return FReply::Handled();  
            })  
        \]  
\];  

}

void FPackageHelperModule::StartupModule()
{
FPackageHelperStyle::Initialize();
FPackageHelperStyle::ReloadTextures();
FPackageHelperCommands::Register();

PluginCommands = MakeShareable(new FUICommandList);

PluginCommands->MapAction(  
    FPackageHelperCommands::Get().PluginAction,  
    FExecuteAction::CreateRaw(this, &FPackageHelperModule::PluginButtonClicked),  
    FCanExecuteAction());

UToolMenus::RegisterStartupCallback(FSimpleMulticastDelegate::FDelegate::CreateRaw(this, &FPackageHelperModule::RegisterMenus));

FGlobalTabmanager::Get()->RegisterNomadTabSpawner(PackageHelperTabName  
        , FOnSpawnTab::CreateRaw(this, &FPackageHelperModule::WindowBody))  
    .SetDisplayName(LOCTEXT("PackageHelper", "PackageHelper"))  
    .SetMenuType(ETabSpawnerMenuType::Hidden);  

}

void FPackageHelperModule::ShutdownModule()
{
UToolMenus::UnRegisterStartupCallback(this);
UToolMenus::UnregisterOwner(this);

FPackageHelperStyle::Shutdown();  
FPackageHelperCommands::Unregister();

FGlobalTabmanager::Get()->UnregisterNomadTabSpawner(PackageHelperTabName);  

}

void FPackageHelperModule::PluginButtonClicked()
{
FGlobalTabmanager::Get()->TryInvokeTab(PackageHelperTabName);
}

void FPackageHelperModule::RegisterMenus()
{
FToolMenuOwnerScoped OwnerScoped(this);
{
UToolMenu* Menu = UToolMenus::Get()->ExtendMenu("LevelEditor.MainMenu.Window");
{
FToolMenuSection& Section = Menu->FindOrAddSection("WindowLayout");
Section.AddMenuEntryWithCommandList(FPackageHelperCommands::Get().PluginAction, PluginCommands);
}
}

{  
    UToolMenu\* ToolbarMenu = UToolMenus::Get()->ExtendMenu("LevelEditor.LevelEditorToolBar");  
    {  
        FToolMenuSection& Section = ToolbarMenu->FindOrAddSection("Settings");  
        {  
            FToolMenuEntry& Entry = Section.AddEntry(FToolMenuEntry::InitToolBarButton(FPackageHelperCommands::Get().PluginAction));  
            Entry.SetCommandList(PluginCommands);  
        }  
    }  
}  

}

#undef LOCTEXT_NAMESPACE

IMPLEMENT_MODULE(FPackageHelperModule, PackageHelper)

PackageHelper.cpp

2.DefaultEngine.ini配置文件修改

因为打包不同内容加载的地图也不一样,所以在打包前先在配置文件里更新GameDefaultMap,

虽然RunUAT.bat也可以传入打包地图,但那样灵活性稍差一些。

此处使用GConfig写入配置文件:

FString MapPath;//要用UE路径格式,例如:Game/Maps/ThirdPersonExampleMap.ThirdPersonExampleMap
FString Path = FPaths::ConvertRelativePathToFull(FPaths::ProjectConfigDir() + TEXT("DefaultEngine.ini"));
GConfig->SetString(TEXT("/Script/EngineSettings.GameMapsSettings"), TEXT("GameDefaultMap"), *MapPath, *Path);
GConfig->Flush(false, *Path);//Read参数为false是针对写入Flush,true是针对读取

3.RunUAT.bat打包

与Unity直接封装好了打包函数不同,UE中需要用RunUAT.bat打包,位于引擎目录:

Engine/Build/BatchFiles/RunUAT.bat

打包时,需要阻塞UE自身线程,这样可以在打包完成后做一些事情,

这里使用FPlatformProcess运行RunUAT.bat,具体代码如下:

//打包函数,参数BuildPath为打包输出目录(注意路径结尾不带斜杠,否则打包失败)
void BuildPackage(FString BuildPath)
{
FString RunUATPath = FPaths::ConvertRelativePathToFull(FPaths::EngineDir())
+ FString("Build/BatchFiles/RunUAT.bat");
FString UE4EditorCmdPath = FPaths::ConvertRelativePathToFull(FPaths::EngineDir())
+ FString("Binaries/Win64/UE4Editor-Cmd.exe");
FString UProjectPath = FPaths::ConvertRelativePathToFull(FPaths::GameSourceDir()
+ TEXT("../"));

TArray<FString> AssetName;  
IFileManager::Get().FindFiles(AssetName, \*UProjectPath, TEXT(".uproject"));  
UProjectPath += AssetName\[0\];

FString Arg = FString("-ScriptsForProject=\\"" + UProjectPath + "\\" BuildCookRun -project=\\""  
    + UProjectPath +"\\" -targetplatform=Win64 -clientconfig=Development -ue4exe=\\""  
    + UE4EditorCmdPath + "\\" -noP4 -iterate -cook -pak -package -stage -archive -archivedirectory=\\""  
    + BuildPath + "\\" -nocompileeditor -prereqs -nodebuginfo -build -CrashReporter -utf8output -compressed");

FProcHandle Handle = FPlatformProcess::CreateProc(\*RunUATPath, \*Arg  
    , false, false, false, nullptr  
    , 2, nullptr, nullptr);  
//创建进程打包,PriorityModifer可以填2,进程优先级会高一些

FPlatformProcess::WaitForProc(Handle);  
//堵塞,等待新进程打包完成

UE\_LOG(LogTemp, Log, TEXT("Package Successful!"));  
//这里可以加一些打包完的后续操作  

}

这样重启UE之后即可使用打包工具,提升开发效率。

最后Build.cs中还需要添加一些模块依赖,参考如下:

PrivateDependencyModuleNames.AddRange(
new string[]
{
"Projects",
"InputCore",
"UnrealEd",
"ToolMenus",
"CoreUObject",
"Engine",
"Slate",
"SlateCore",
"EngineSettings"
}
);

Build.cs依赖模块参考

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章