UE4自动打包工具编写

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

本文就来实现一下这个功能。

UE4自动打包工具编写

UE4自动打包工具编写

 

1.插件编写

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

UE4自动打包工具编写

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

.cpp部分代码如下:

UE4自动打包工具编写

#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<SDockTab> 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中还需要添加一些模块依赖,参考如下:

UE4自动打包工具编写

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

Build.cs依赖模块参考

 

发表评论

评论已关闭。

相关文章