- Desarrollo del Complemento
Para proyectos en UE4 que requieren compilaciones múltiples, es útil contar con una herramienta automatizada con interfaz gráfica. Se implementa un complemento (para UE 4.27) que facilita este proceso.
Comienza creando el complemento mediante la plantilla estándar de UE4. Registra una interfaz Slate y lógica de apertura. El botón en la UI invoca la función principal.
Fragmento de código del archivo principal (.cpp):
#include "BuildAssistantModule.h"
#include "BuildAssistantStyle.h"
#include "BuildAssistantCommands.h"
#include "Misc/MessageDialog.h"
#include "ToolMenus.h"
#include "GameMapsSettings.h"
#include "Misc/FileHelper.h"
#include "FileHelpers.h"
static const FName AssistantTabID("BuildAssistant");
#define LOCTEXT_NAMESPACE "FBuildAssistantModule"
TSharedRef<SDockTab> FBuildAssistantModule::CreateMainPanel(const FSpawnTabArgs& Args)
{
return SNew(SDockTab)
.TabRole(ETabRole::NomadTab)
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
[
SNew(SButton)
.Content()
[
SNew(STextBlock)
.Justification(ETextJustify::Center)
.Text(LOCTEXT("GenerateBuildA", "Generate Build A"))
]
.OnClicked_Lambda([this]()
{
// Lógica para compilación A
return FReply::Handled();
})
]
+ SVerticalBox::Slot()
[
SNew(SButton)
.Content()
[
SNew(STextBlock)
.Justification(ETextJustify::Center)
.Text(LOCTEXT("GenerateBuildB", "Generate Build B"))
]
.OnClicked_Lambda([this]()
{
// Lógica para compilación B
return FReply::Handled();
})
]
];
}
void FBuildAssistantModule::StartupModule()
{
FBuildAssistantStyle::Initialize();
FBuildAssistantStyle::ReloadTextures();
FBuildAssistantCommands::Register();
CommandsList = MakeShareable(new FUICommandList);
CommandsList->MapAction(
FBuildAssistantCommands::Get().MainAction,
FExecuteAction::CreateRaw(this, &FBuildAssistantModule::OnToolbarButtonClicked),
FCanExecuteAction());
UToolMenus::RegisterStartupCallback(FSimpleMulticastDelegate::FDelegate::CreateRaw(this, &FBuildAssistantModule::RegisterExtensions));
FGlobalTabmanager::Get()->RegisterNomadTabSpawner(AssistantTabID,
FOnSpawnTab::CreateRaw(this, &FBuildAssistantModule::CreateMainPanel))
.SetDisplayName(LOCTEXT("AssistantTab", "Build Assistant"))
.SetMenuType(ETabSpawnerMenuType::Hidden);
}
void FBuildAssistantModule::ShutdownModule()
{
UToolMenus::UnRegisterStartupCallback(this);
UToolMenus::UnregisterOwner(this);
FBuildAssistantStyle::Shutdown();
FBuildAssistantCommands::Unregister();
FGlobalTabmanager::Get()->UnregisterNomadTabSpawner(AssistantTabID);
}
void FBuildAssistantModule::OnToolbarButtonClicked()
{
FGlobalTabmanager::Get()->TryInvokeTab(AssistantTabID);
}
void FBuildAssistantModule::RegisterExtensions()
{
FToolMenuOwnerScoped OwnerScoped(this);
UToolMenu* Menu = UToolMenus::Get()->ExtendMenu("LevelEditor.MainMenu.Window");
FToolMenuSection& Section = Menu->FindOrAddSection("LayoutSection");
Section.AddMenuEntryWithCommandList(FBuildAssistantCommands::Get().MainAction, CommandsList);
UToolMenu* Toolbar = UToolMenus::Get()->ExtendMenu("LevelEditor.LevelEditorToolBar");
FToolMenuSection& ToolbarSection = Toolbar->FindOrAddSection("ConfigSection");
FToolMenuEntry& ToolbarEntry = ToolbarSection.AddEntry(FToolMenuEntry::InitToolBarButton(FBuildAssistantCommands::Get().MainAction));
ToolbarEntry.SetCommandList(CommandsList);
}
#undef LOCTEXT_NAMESPACE
IMPLEMENT_MODULE(FBuildAssistantModule, BuildAssistant)
- Ajustes en Archivos de Configuración
Al empaquetar diferentes contenidos, el mapa de inicio puede variar. Se actualiza el archivo DefaultEngine.ini antes de la compilación para especificar el mapa predeterminado.
Se utiliza la API de configuración de UE4:
FString CurrentMap = TEXT("Game/Maps/ExampleMap.ExampleMap");
FString ConfigFilePath = FPaths::ConvertRelativePathToFull(FPaths::ProjectConfigDir() + TEXT("DefaultEngine.ini"));
GConfig->SetString(TEXT("/Script/EngineSettings.GameMapsSettings"), TEXT("GameDefaultMap"), *CurrentMap, *ConfigFilePath);
GConfig->Flush(false, *ConfigFilePath);
- Ejecución del Empaquetado con RunUAT.bat
UE4 rqeuiere el uso del script RunUAT.bat para el empaquetado, a diferencia de otros motores. Este script se encuentra en el directorio del motor: Engine/Build/BatchFiles/RunUAT.bat.
Para mantener la sincronización, se bloquea el hilo principal de UE durante la ejecución:
void ExecuteBuildProcess(FString OutputPath)
{
FString ScriptPath = FPaths::ConvertRelativePathToFull(FPaths::EngineDir()) + TEXT("Build/BatchFiles/RunUAT.bat");
FString EditorCmd = FPaths::ConvertRelativePathToFull(FPaths::EngineDir()) + TEXT("Binaries/Win64/UE4Editor-Cmd.exe");
FString ProjectRoot = FPaths::ConvertRelativePathToFull(FPaths::GameSourceDir() + TEXT("../"));
TArray<fstring> ProjectFiles;
IFileManager::Get().FindFiles(ProjectFiles, *ProjectRoot, TEXT(".uproject"));
if (ProjectFiles.Num() > 0)
{
ProjectRoot += ProjectFiles[0];
}
FString Arguments = FString::Printf(
TEXT("-ScriptsForProject=\"%s\" BuildCookRun -project=\"%s\" -targetplatform=Win64 -clientconfig=Development -ue4exe=\"%s\" -noP4 -iterate -cook -pak -package -stage -archive -archivedirectory=\"%s\" -nocompileeditor -prereqs -nodebuginfo -build -CrashReporter -utf8output -compressed"),
*ProjectRoot, *ProjectRoot, *EditorCmd, *OutputPath
);
FProcHandle ProcessHandle = FPlatformProcess::CreateProc(*ScriptPath, *Arguments,
false, false, false, nullptr, 2, nullptr, nullptr);
FPlatformProcess::WaitForProc(ProcessHandle);
UE_LOG(LogTemp, Log, TEXT("Empaquetado completado con éxito."));
}
</fstring>
Tras reiniciar UE4, la herramienta estará operativa en la barra de herramientas y el menú de ventanas.
Finalmente, asegúrate de añadir las dependencias necesarias en el archivo Build.cs:
PrivateDependencyModuleNames.AddRange(
new string[]
{
"Projects",
"InputCore",
"UnrealEd",
"ToolMenus",
"CoreUObject",
"Engine",
"Slate",
"SlateCore",
"EngineSettings"
}
);