序言
使用UE版本为UE5.20
在实际项目中,我们常常使用自动化脚本来进行构建,它可以增加我们的生产效率,并降低人为操作带来的失误风险。
BuildGraph
BuildGraph UE官方提供的构建脚本系统,它可以读取对应的XML脚本实现自动化打包。
BuildGraph相关的参考BuildGraph | UE文档
重点是它相关的语法
自动化脚本
自动化脚本我打算使用(.bat / .sh)“壳”文件作为入口,运行py脚本并拉起运行BuildGraph命令的UAT,并且设定相关的参数。
Build.bat
python3 Build.py
运行该目录的py脚本
Build.py
import sys import os def main(argv): ProjectName = "BuildTest" ProjectDir = r"E:/AllProject/UE_5_2_0/BuildTest/" Platform = "Android" ClientConfig = "Development" OutputDir = r"E:/AllProject/UE_5_2_0/BuildTest/PakOutputX" SkipBuildProject = "true" SkipBuildEditor = "true" Unrealexe = r"E:UEUE_4.27_SourceUnrealEngineEngineBinariesWin64UnrealEditor-Cmd.exe " EditorIOPort = "54689" cmd = f"-set:ProjectName={ProjectName} -set:ProjectDir={ProjectDir} -set:Platform={Platform}" f" -set:ClientConfig={ClientConfig} -set:OutputDir={OutputDir} -set:SkipBuildProject={SkipBuildProject}" f" -set:SkipBuildEditor={SkipBuildEditor} -set:Unrealexe={Unrealexe} -set:EditorIOPort={EditorIOPort}" fileDir = r"E:UEUE_4.27_SourceUnrealEngineEngineBuildBatchFilesRunUAT.bat" target = "MyBuild" script = r"E:AllProjectUE_5_2_0BuildTestBuildToolsBuild.xml" cmd = f"{fileDir} BuildGraph -Script={script} -Target={target} {cmd}" print(f"cmd: {cmd}") ret = os.system(cmd) if ret == 0: print(f"run build ret val = {ret}") else: raise Exception("project build faild!") pass if __name__ == "__main__": main(sys.argv[1:]) input("press any to close")
这个py主要是拼接了参数到命令里面,方便配置命令。命令拼接好后拉起RunUAT.bat运行BuildGraph命令并传递命令参数。
注意target是我们后面Build.xml脚本里的MyBuild那个Agent
cmd: 打印了拼接的命令。
BuildGraph脚本Build.xml
<?xml version='1.0' ?> <BuildGraph xmlns="http://www.epicgames.com/BuildGraph" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.epicgames.com/BuildGraph ../../Engine/Build/Graph/Schema.xsd"> <!-- Base Options --> <Option Name="ProjectName" DefaultValue="" Description="project path like D:UEProjBuildTestBuildTest.uproject" /> <Option Name="ProjectDir" DefaultValue="" Description="for run BuildGraph scripts uproject, same as ProjectPath usually" /> <Option Name="Platform" DefaultValue="" Description="target platform like Windows, Android, IOS and so on"/> <Option Name="ClientConfig" DefaultValue="Development" Description="config like Debug, Development, Shipping" /> <Option Name="OutputDir" DefaultValue="" Description="" /> <Option Name="SkipBuildProject" DefaultValue="true" Description="skip build project default = true" /> <Option Name="SkipBuildEditor" DefaultValue="true" Description="skip build editor default = true " /> <Option Name="Unrealexe" DefaultValue="" Description="like UnrealEngineEngineBinariesWin64UnrealEditor-Cmd.exe" /> <Option Name="EditorIOPort" DefaultValue="64752" Description="ensure the port unuse" /> <!-- Advance Options--> <Option Name="WithClean" DefaultValue="false" Description="clean before build" /> <Option Name="WithCook" DefaultValue="true" Description="cook assets" /> <Property Name="ProjectFullName" Value="$(ProjectDir)$(ProjectName).uproject" /> <!-- Base --> <Property Name="BaseCmd" Value="-project=$(ProjectFullName) -ScriptsForProject=$(ProjectFullName)" /> <!-- Check SDK Command --> <Property Name="CheckSDKCmd" Value="Turnkey -command=VerifySdk -platform=Android -UpdateIfNeeded" If="$(Platform) == Android" /> <!-- Editor IO Command --> <Property Name="EditorIOCmd" Value="-EditorIO -EditorIOPort=$(EditorIOPort)" /> <!-- Sub Command --> <Property Name="CleanCmd" Value="" /> <Property Name="CleanCmd" Value="-clean" If="$(WithClean)" /> <Property Name="HeadCmd" Value="BuildCookRun -project=$(ProjectFullName) -target=BuildTest -platform=$(Platform)" /> <Property Name="HeadCmd" Value="$(HeadCmd) -cookflavor=ASTC" If="$(Platform) == Android" /> <Property Name="HeadCmd" Value="$(HeadCmd) -prereqs -nop4 -utf8output -Unrealexe=$(Unrealexe)" /> <Property Name="BuildCmd" Value="-build -clientconfig=$(ClientConfig)" /> <Property Name="BuildCmd" Value="$(BuildCmd) -nocompile -nocompileuat" If="$(SkipBuildProject)" /> <Property Name="BuildCmd" Value="$(BuildCmd) -nocompileeditor -skipbuildeditor" If="$(SkipBuildEditor)" /> <Property Name="CookCmd" Value="-cook -iostore -compressed" /> <Property Name="CookCmd" Value="$(BuildCmd) -skipcook" If="$(WithCook) == false" /> <Property Name="PakCmd" Value="-pak" /> <Property Name="StageCmd" Value="-stage" /> <Property Name="PackageCmd" Value="-package" /> <Property Name="ArchiveCmd" Value="-archive -archivedirectory=$(OutputDir)" /> <!-- Client Command --> <Property Name="ClientCmd" Value="$(BaseCmd) $(CheckSDKCmd) $(EditorIOCmd) $(HeadCmd) $(BuildCmd) $(CookCmd) $(PakCmd) $(StageCmd) $(PackageCmd) $(ArchiveCmd)" /> <!-- Build --> <Agent Name="MyBuild" Type="BuildOnWindows"> <Node Name="MyBuildNode"> <Log Message="BuildCookRun with arguments: $(ClientCmd)" /> <Command Name="BuildCookRun" Arguments="$(ClientCmd)" /> </Node> </Agent> </BuildGraph>
这个脚本就是进行根据条件拼接BuildCookRun的UAT命令,它的参数可以在上一章的使用UAT打包构建的命令中找到(也可以参考后面示例的输出日志)。
BuildGraph 的命令的Target是MyBuild,MyBuild执行了BuildCookRun这个Command并把拼接命令传递过去。
日志和执行结果
日志

圈出的地方分别是py和Build.xml输出的命令行
执行结果


结语
- 在打包的时候使用BuildGraph这一步不是必须的,完全可以直接使用py拼接BuildCookRun的命令,拉起UAT执行。不过BuildGraph在构建Editor时因为有现成的脚本会更方便些。
- 这是在UE5.20环境下测试的,在UE4上应该是大同小异的
- 这个是基于基本打包命令实现的,实际生产环境会控制更多的参数以及其他一些定制化的修改