本篇文章边试验遍写
// 持续更新,不更新了我就把这行删了
由于懒惰,还是不更新了~~
打包平台:Win64
Package
首先要找到源码相关位置,在整个解决方案搜索Package Project,然后在MainMenu.cpp中找到以下代码,即编辑器创建Package Project这个选项的位置
Section.AddSubMenu(
"PackageProject",
LOCTEXT("PackageProjectSubMenuLabel", "Package Project"),
LOCTEXT("PackageProjectSubMenuToolTip", "Compile, cook and package your project and its content for distribution."),
FNewMenuDelegate::CreateStatic( &FPackageProjectMenu::MakeMenu ), false, FSlateIcon(FEditorStyle::GetStyleSetName(), "MainFrame.PackageProject")
);
从FPackageProjectMenu::MakeMenu往下追踪找到打包平台按钮创建位置
PackageProjectMenu.h
static void AddPlatformToMenu(FMenuBuilder& MenuBuilder, const PlatformInfo::FPlatformInfo& PlatformInfo)
接着向下追踪,找到MainFrameActions.h
FMainFrameActionCallbacks::PackageProject,这应该就是打包调用的函数了
打上断点测试确实如此
首先是一长串打包条件的检测(略)
获取打包配置,也就是ProjectSetting->Packaging内的配置
UProjectPackagingSettings* PackagingSettings = Cast<UProjectPackagingSettings>(UProjectPackagingSettings::StaticClass()->GetDefaultObject());
弹出打包目录选择窗口
if (!FDesktopPlatformModule::Get()->OpenDirectoryDialog(ParentWindowWindowHandle, LOCTEXT("PackageDirectoryDialogTitle", "Package project...").ToString(), PackagingSettings->StagingDirectory.Path, OutFolderName))
之后将打包配置转为字符串参数OptionalParams
最终含代码的空项目的参数:
-pak -prereqs -nodebuginfo -targetplatform=Win64 -build -target=TestProj -clientconfig=Development
拼接好的传给FUATHelperModule的打包命令:
-ScriptsForProject=\"E:/Document/UnrealProjects/TestProj/TestProj.uproject\" BuildCookRun -nocompileeditor -nop4 -project=\"E:/Document/UnrealProjects/TestProj/TestProj.uproject\" -cook -stage -archive -archivedirectory=\E:/Document/Unrealprojects/Testproj/package\ -package -ue4exe=\E:\\Engine\\4.24\\Engine\\Binaries\\Win64\\UE4Editor-Cmd.exe\ -pak -prereqs -nodebuginfo -targetplatform=Win64 -build -target=Testproj -clientconfig=Development -utf8output
然后创建打包任务
IUATHelperModule::Get().CreateUatTask( CommandLine, PlatformInfo->DisplayName, LOCTEXT("PackagingProjectTaskName", "Packaging project"), LOCTEXT("PackagingTaskName", "Packaging"), FEditorStyle::GetBrush(TEXT("MainFrame.PackageProject")) );
接下来交给UAT处理,这里又是拼接完整的命令
#if PLATFORM_WINDOWS
FString FullCommandLine = FString::Printf(TEXT("/c \"\"%s\" %s\""), *UatPath, *CommandLine);
#else
FString FullCommandLine = FString::Printf(TEXT("\"%s\" %s"), *UatPath, *CommandLine);
#endif
拼接结果:
/c ""E:/Engine/4.24/Engine/Build/BatchFiles/RunUAT.bat" -ScriptsForProject=\"E:/Document/UnrealProjects/TestProj/TestProj.uproject\" BuildCookRun -nocompileeditor -nop4 -project=\"E:/Document/UnrealProjects/TestProj/TestProj.uproject\" -cook -stage -archive -archivedirectory=\E:/Document/Unrealprojects/Testproj/package\ -package -ue4exe=\E:\\Engine\\4.24\\Engine\\Binaries\\Win64\\UE4Editor-Cmd.exe\ -pak -prereqs -nodebuginfo -targetplatform=Win64 -build -target=Testproj -clientconfig=Development -utf8output"
在这里绑定了打包任务相关的回调事件:
UatProcess->OnCanceled().BindStatic(&FUATHelperModule::HandleUatProcessCanceled, NotificationItemPtr, PlatformDisplayName, TaskShortName, Data);
UatProcess->OnCompleted().BindStatic(&FUATHelperModule::HandleUatProcessCompleted, NotificationItemPtr, PlatformDisplayName, TaskShortName, Data);
UatProcess->OnOutput().BindStatic(&FUATHelperModule::HandleUatProcessOutput, NotificationItemPtr, PlatformDisplayName, TaskShortName);
通过UatProcess->Launch() 创建打包进程,Launch()代码全贴出来并加上注释
MonitoredProcess.cpp
bool FMonitoredProcess::Launch()
{
if (bIsRunning)
{
return false;
}
check (Thread == nullptr); // We shouldn't be calling this twice
if (bCreatePipes && !FPlatformProcess::CreatePipe(ReadPipe, WritePipe))
{
return false;
}
//这之前都为防错校验
//此行为调用CMD命令,仅说明URL和Params值
// URL: "cmd.exe"
// Params: 之前拼接好的命令,这里不再说明
// 其实就相当于打开cmd,将之前拼接好的命令输入
ProcessHandle = FPlatformProcess::CreateProc(*URL, *Params, false, Hidden, Hidden, nullptr, 0, *WorkingDir, WritePipe);
if (!ProcessHandle.IsValid())
{
return false;
}
static int32 MonitoredProcessIndex = 0;
const FString MonitoredProcessName = FString::Printf( TEXT( "FMonitoredProcess %d" ), MonitoredProcessIndex );
MonitoredProcessIndex++;
bIsRunning = true;
Thread = FRunnableThread::Create(this, *MonitoredProcessName, 128 * 1024, TPri_AboveNormal);
if ( !FPlatformProcess::SupportsMultithreading() )
{
StartTime = FDateTime::UtcNow();
}
return true;
}
可以发现其实是调用的RunUAT.bat,打开RunUAT.bat查看内容,啊~老多文本了。。
看这个批处理可以发现是传参给AutomationTool.exe去处理了。打住,基本上项目已经够用了,后续我再康康AutomatonTool源码
COOK
同理找到源码位置:Engine\Source\Editor\MainFrame\Private\Frame\MainFrameActions.h
static void CookContent( const FName InPlatformInfoName );
跟完发现其实出了最开始参数拼接不同外,其他流程是一样的,都是传参给AutomationTool.exe处理,不过参数不同