unreal自动化打包

由于是第一个项目,之前一直都是手动打包,所以最近要看看ci打包的事情!

知识前提

以上这三个是必然会使用到的!如果还没有接触的可以自行去看看官方的连接!

文档上的知识在这里就不照搬了!进入主题吧!

基本的结构

All.xml是所有任务的汇总 Properties.xml是整个自动化用到的属性(变量) Reset.xml是用来按需配置打包的,不用平台可能有不同的需求 PakResource.xml是pak资源的 BuildScript.xml是编译和打包的

过程及问题

ci 环境的搭建

Unreal 项目CI打包环境

具体的xml以及注意

All.xml

All.xml是一个汇总,文件划分已经做好的 All.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 ../Schema.xsd" >
	<Include Script="Properties.xml"/>
	<Include Script="Reset.xml"/>
	<Include Script="BuildScript.xml"/>
	<Include Script="PakResource.xml"/>
	<Aggregate Name="All" Requires="Properties Module;Reset Module;Pak Resource Module;Build Script Module"/>
	<Aggregate Name="Reset" Requires="Properties Module;Reset Module"/>
	<Aggregate Name="Pak" Requires="Properties Module;Build Project;Pak Resource Module"/>
	<Aggregate Name="Build" Requires="Properties Module;Build Script Module"/>
</BuildGraph>

这里有个问题,如果是Aggregate所依赖的Modeule有交叉的话,最好是把所有的Aggregate都写到一个大的xml中!

Properties.xml

Properties.xml基本是属性的声明 目前项目使用到了lua,需要对Lua进行单独的pak打包 Properties.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 ../Schema.xsd" >

	<!-- Option Begins -->
    <Option Name="BuildConfiguration" DefaultValue="Development" Description="Debug, Development or Shipping."/>
    <Option Name="WithClean" DefaultValue="false" Description="Clean before build."/>
    <Option Name="WithDebugInfo" DefaultValue="false" Description="Enable debug info in Development and Shipping."/>
    <Option Name="WithCook" DefaultValue="true" Description="Cook asset."/>
    <Option Name="IgnoreCookErrors" DefaultValue="false" Description=""/>
    <Option Name="IterativeCooking" DefaultValue="false" Description=""/>
    <Option Name="ProjectDir" DefaultValue="" Description="项目目录"/>
    <Option Name="ProjectName" DefaultValue="" Description="项目名称"/>
    <Option Name="BuildTarget" DefaultValue="Android" Description="打包的类型"/>
    <Option Name="IsPakLua" DefaultValue="true" Description="是否打包lua"/>
    <Option Name="IsPackage" DefaultValue="true" Description="是否打包成ipa/apk"/>
    <!-- Option Ends -->

    <!-- Command Begins -->
	<Property Name="UnrealProjectDir" Value="$(ProjectDir)/UnrealProject"/>
    <!-- CleanCommand -->
    <Property Name="CleanCommand" Value="" />
    <Property Name="CleanCommand" Value="-Clean" If="$(WithClean)"/>
    <!-- BuildCommand -->
    <Property Name="BuildCommand" Value="-Build -NoCompileEditor -SkipBuildEditor"/>
    <Property Name="BuildCommand" Value="$(BuildCommand) -ForceDebugInfo" If="$(WithDebugInfo)"/>
    <!-- PakCommand -->
    <Property Name="PakCommand" Value="-Pak"/>
    <!-- CookCommand -->
    <Property Name="CookCommand" Value="-Cook -SkipCookingEditorContent -UnversionedCookedContent -CookPartialgc -Compressed"/>
    <Property Name="CookCommand" Value="$(CookCommand) -IgnoreCookErrors" If="$(IgnoreCookErrors)"/>
    <Property Name="CookCommand" Value="$(CookCommand) -IterativeCooking" If="$(IterativeCooking)"/>
    <Property Name="CookCommand" Value="-SkipCook" If="'$(WithCook)' == false"/>
    <!-- StageCommand -->
    <Property Name="StageCommand" Value="-Stage"/>
    <!-- PackageCommand -->
    <Property Name="PackageCommand" Value=""/>
    <Property Name="PackageCommand" Value="-Package" If="$(IsPackage)"/>
    <!-- ArchiveCommand -->
    <Property Name="ArchiveCommand" Value="-Archive -ArchiveDirectory=$(ProjectDir)/Binaries"/>
    <!-- Command -->
    <Property Name="BaseCommand" Value="-project=$(ProjectDir)/UnrealProject/$(ProjectName).uproject -UTF8Output -NoP4 -Prereqs $(CleanCommand) $(BuildCommand) $(PakCommand) $(CookCommand) $(StageCommand) $(ArchiveCommand)"/>
    <Property Name="BaseGameCommand" Value="$(BaseCommand) -ClientConfig=$(BuildConfiguration) $(PackageCommand)"/>
    <Property Name="BaseServerCommand" Value="$(BaseCommand) -DedicatedServer"/>

    <!-- Configs Begins -->
    <!-- Android -->
    <Property Name="SDKPath" Value="(Path=&quot;C:/Users/UE/AppData/Local/Android/Sdk&quot;)"/>
    <Property Name="NDKPath" Value="(Path=&quot;C:/Users/UE/AppData/Local/Android/Sdk/ndk/21.4.7075529&quot;)"/>
    <Property Name="JavaPath" Value="(Path=&quot;C:/android/OpenJDK&quot;)"/>
    <Property Name="SDKAPILevel" Value="latest"/>
    <Property Name="NDKAPILevel" Value="android-21"/>
    <!-- Android Ends -->

    <Property Name="StartMap" Value="/Game/Starter/GameStarter.GameStarter"/>
    <Property Name="StartMap" Value="/Game/Starter/GameStarter.GameStarter" If="'$(BuildTarget)'=='Android'"/>
    <!--<Property Name="DirectoriesToNeverCook" Value="(Path=&quot;/Game/TA_Demo&quot;)"/>-->
    <Property Name="DirectoriesToNeverCook" Value="(Path=&quot;/Game/TA_Demo/Levels&quot;)
    &#xA;+DirectoriesToNeverCook=(Path=&quot;/Game/TA_Demo/AnimStarterPack&quot;)
    &#xA;+DirectoriesToNeverCook=(Path=&quot;/Game/TA_Demo/StarterContent&quot;)
    &#xA;+DirectoriesToNeverCook=(Path=&quot;/Game/TA_Demo/Stylized_Forest&quot;)
    &#xA;+DirectoriesToNeverCook=(Path=&quot;/Game/TA_Demo/Stylized_Landscape&quot;)
    &#xA;+DirectoriesToNeverCook=(Path=&quot;/Game/TA_Demo/StylizedLandscapeKit&quot;)"/>
    <!-- 如果是多行的话 -->
    <!--
        <Property Name="DirectoriesToNeverCook" Value="(Path=&quot;/Game/TA_Demo/Levels&quot;)
        &#xA;+DirectoriesToNeverCook=(Path=&quot;/Game/TA_Demo/Levels&quot;)"/>
    -->
    <!-- Configs Ends -->
	<!-- Property Ends -->
	
	<Agent Name="Properties Agent" Type="AutoBuild">
		<Node Name="Properties Module">
			<Log Message="==============完成属性配置====================="/>
			<Log Message="ProjectDir:$(ProjectDir)"/>
			<Log Message="ProjectName:$(ProjectName)"/>
			<Log Message="BaseGameCommand:$(BaseGameCommand)"/>
			<Log Message="==================================="/>
		</Node>
	</Agent>
	
</BuildGraph>

因为是Properties, 所以字符串是少不了的,但是需要注意xml的一些转码! 这里提供目前我使用的,如果是其他的,可以自行google哈 &quot; : “ &#xA; : 换行

PakResource.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 ../Schema.xsd" >
	<Agent Name="Pak Resource Agent" Type="AutoBuild">
		<Node Name="Delete BuildGraph Lua">
			<Do If="Exists('$(ProjectDir)/BuildGraph/')">
				<Delete Files="$(ProjectDir)/BuildGraph/**" />
			</Do>
		</Node>
		<Node Name="Find Framework Lua File" Requires="Delete BuildGraph Lua" Produces="#FrameworkLuaFiles">
			<!-- 一定要在$(ProjectDir)/BuildGraph下多个Lua文件夹作为MountPoint,要不然pak的时候会报错!-->
			<Copy From="$(UnrealProjectDir)/Plugins/myPlugin/Content/Lua/**" To="$(ProjectDir)/BuildGraph/Lua/Plugins/myPlugin/Content/Lua/**" Overwrite="true" Tag="#FrameworkLuaFiles"/>
		</Node>
		<Node Name="Find Project Lua File" Produces="#ProjectLuaFiles">
			<Copy From="$(UnrealProjectDir)/Content/Lua/**" To="$(ProjectDir)/BuildGraph/Lua/Content/Lua/**" Overwrite="true" Tag="#ProjectLuaFiles"/>
		</Node>
		
		<Node Name="Pak Lua" If="!$(IsPakLua)">
			<Log Message="不打包lua"/>
		</Node>
		<Node Name="Pak Lua" Requires="#FrameworkLuaFiles;#ProjectLuaFiles" If="$(IsPakLua)" After="Build Project">
			<Log Message="开始打包lua"/>
			<!-- 一定不能有Response,要不然pak的时候,相对路径会报异常-->
			<PakFile Files="#ProjectLuaFiles;#FrameworkLuaFiles" Output="$(UnrealProjectDir)/Content/Paks/Lua.pak" RebaseDir="$(ProjectDir)/BuildGraph/"/>
			<Log Message="完成打包lua"/>
		</Node>
		<Node Name="Pak Resource Module" Requires="Pak Lua">
			<Log Message="执行 Pak Resource Module 完成"/>
		</Node>
	</Agent>
</BuildGraph>

这个目前只是用来打包lua的,至于以后会不会将资源cook和独立打包资源也加进去就待定了!

BuildScript.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 ../Schema.xsd" >
	<Agent Name="Tools Win64" Type="AutoBuild">
        <Node Name="Build Tools Win64">
            <Compile Target="ShaderCompileWorker" Configuration="DebugGame" Platform="Win64" Tag="#Build Tools Win64" Clean="false"/>
			<Log Message="========================ShaderCompileWorker Finish"/>
            <Compile Target="UnrealPak" Configuration="DebugGame" Platform="Win64" Tag="#Build Tools Win64" Clean="false"/>
			<Log Message="========================UnrealPak Finish"/>
			<Compile Target="UnrealHeaderTool" Configuration="DebugGame" Platform="Win64" Tag="#UHTFiles" Clean="false"/>
			<Log Message="========================UnrealHeaderTool Finish"/>
        </Node>
    </Agent>
	<Agent Name="Build Project Agent" Type="CompileWin64">
		<Node Name="Build Project" Requires="Build Tools Win64">
			<!-- 一定要先generate -->
			<!--<Compile Target="UE4Client" Platform="Win64" Configuration="Development"/>-->
			<!-- 一定要声明Clean,要不然每次都有几千个文件要编译!!!-->
			<Compile Target="$(ProjectName)Editor" Platform="Win64" Configuration="Development" Arguments="$(UnrealProjectDir)/$(ProjectName).uproject" Clean="false"/>
			<Log Message="Build Project Finish"/>
		</Node>
	</Agent>
	<Agent Name="Game Win64" Type="AutoBuild">
        <Node Name="Build Game Win64">
            <Property Name="Win64GameCommand" Value="-TargetPlatform=Win64 $(BaseGameCommand)"/>
            <Log Message="================BuildCookRun with arguments: $(Win64GameCommand)"/>
            <Command Name="BuildCookRun" Arguments="$(Win64GameCommand)"/>
        </Node>
    </Agent>
	<Agent Name="Game Android" Type="AutoBuild">
        <Node Name="Build Game Android">
            <Property Name="AndroidGameCommand" Value="-TargetPlatform=Android -CookFlavor=ETC2 $(BaseGameCommand)"/>
            <Log Message="================BuildCookRun with arguments: $(AndroidGameCommand)"/>
            <Command Name="BuildCookRun" Arguments="$(AndroidGameCommand)"/>
        </Node>
    </Agent>

    <Agent Name="Game iOS" Type="AutoBuild">
        <Node Name="Build Game iOS">
            <Property Name="iOSGameCommand" Value="-TargetPlatform=IOS $(BaseGameCommand)"/>
            <Log Message="================BuildCookRun with arguments: $(iOSGameCommand)"/>
            <Command Name="BuildCookRun" Arguments="$(iOSGameCommand)"/>
        </Node>
    </Agent>
	<!-- 打包脚本的开始 -->
	<Agent Name="Build Script Agent" Type="AutoBuild">
		<Node Name="Build Script Module" If="'$(BuildTarget)' == 'Win32'">
			<Log Message="执行 Build Script Module Win"/>
		</Node>
		<Node Name="Build Script Module" Requires="Build Game Win64" If="'$(BuildTarget)'=='Win64'">
			<Log Message="执行 Build Script Module Win64"/>
		</Node>
		<Node Name="Build Script Module" Requires="Build Game Android" If="'$(BuildTarget)'=='Android'">
			<Log Message="执行 Build Script Module Android"/>
		</Node>
		<Node Name="Build Script Module" Requires="Build Game iOS" If="'$(BuildTarget)'=='IOS'">
			<Log Message="执行 Build Script Module IOS"/>
		</Node>
	</Agent>
</BuildGraph>