首页 > 其他分享 >UE4命令行编译工程入门

UE4命令行编译工程入门

时间:2023-05-19 17:46:45浏览次数:50  
标签:enginePath 入门 工程 BuildCookRun projectPath 编译 sh UE4 打包

0 背景

笔者是个UE4的小白,本文主要记录了一个小白是如何从零UE4的基础,一步步在命令行打出iOS的ipa包的尝试过程,本文比较浅,适合小白做为UE4工程的入门资料(UE大神可自动忽略本文);

1构建流程

UE4工程的构建会涉及以以下几个步骤:

  • 编译所有的源代码;
  • 将所需的内容转化(cook)为目标平台可使用的格式;
  • 将编译后的代码和经过cook的内容打包成一组可发布的文件,如apk,ipa等;

一般使用UAT(Unreal Automation Tool)工具来通过一系列的脚本程序来构建UE4项目,整个打包过程最重要的命令为BuildCookRunBuildCookRun打包命令最核心的几个部分:

  • 构建(Build) :将为所选择的平台编译可执行的文件;
  • 烘培(Cook):通过在特殊模式下执行编辑器来转化资源(把引擎使用的内容格式转化为运行平台可支持的内容格式);
  • 暂存(Stage):通过将可执行文件和内容复制到暂存区,它是开发目录以外的独立目录;
  • 打包(Package):将项目打包成平台原生的分发格式;
  • 部署(Deploy): 将构建版本部署到目标设备;
  • 运行(Run):该阶段在目标平台上启动已封装的项目;

1.1 Cook

UE引擎使用的资源以特定格式来存储的,如png格式存储纹理数据,wav格式存储音频,但UE引擎使用的内容格式可能没有办法在对应的目标运行平台使用(如iOS,Android等),因此对于这些目标平台来说,
必须要先转化所有这些内容后,才能在对应的设备上正常使用。

Cook时有两种模式可以供选择

  • 常规(by the cook):提前执行cook过程,这样构建出的版本可一次性部署转化后的资源,一般可在性能测试或可行性测试时使用该方法;
  • 动态(on the fly): 将cook过程推迟到游戏被部署到对应平台之后,这种方式只需要安装可执行文件和部分其他文件,并在与转化服务器之间的通信时按需请求,命令行使用的参数为-cookonthefly

2 打包方式

UE4工程可以通过两种方式来进行打包:

  • 通过编辑器的File->Package Project->targetPlatform 菜单来打出对应平台的可执行的安装包
  • 通过BuildCookRun命令来打出对应平台的可执行的安装包;

但不管是用哪种方式进行打包,都需要提前在项目设置菜单里设置好对应平台的配置(Project Setting->Platforms);通过在编辑器菜单进行打包的操作没有其他特殊的逻辑,接下来着重来讲一下通过BuildCookRun命令来打包的过程与注意事项;

2.1BuildCookRun命令打包

一个最简单的使用BookCookRun命令来打包iOS平台上的安装包示例:

sh [UE4Root]/Engine/Build/BatchFiles/RunUAT.sh BuildCookRun -project=ProjectName.uproject -clientconfig=Development -targetplatform=IOS

但笔者在刚从远端拉下来的工程代码里执行这个脚本,发现这个命令会执行失败,会报一些依赖的Plugin找不到等错误,但为啥会失败呢?明明也是按照官方文档和网上的操作教程来执行的。

在遇到这个问题后,笔者在本地做了若干的尝试(更改脚本的各种参数),发现参数的修改都不管用,直到发现如果在本地用UE的编辑器打开过这个工程时,这个命令就可以正常构建出iOSipa包时。
发现这个成功的case后,笔者就开始思考为啥用编辑器打开过工程就可以成功呢?难道是编辑器要打开工程时做了一些初始化的操作吗?带着这个疑问,笔者在经历了几次删除工程又拉取工程的迷之操作后,发现用编辑器打开一个新工程时,会经历过一次rebuild的操作,应该就是这个rebuild操作帮忙做了一些初始化的工作。那rebuild操作对应的命令行命令是什么呢?

带着这个疑问,笔者去搜索了一些文档,并在请教了一个有经验的大佬,大佬指点说在构建前需要用引擎脚本GenerateProjectFiles重编一下整体工程,然后再执行构建的脚本就可以,听到这里时,笔者心想原来这么简单的,于是就三下五除二,写下了如下的构建脚本

enginePath="/Users/Shared/Epic Games/UE_4.27/Engine/"
echo "${enginePath}"
echo $projectPath
#找到引擎在对应编译平台的脚本
buildToolPath="${enginePath}Build/BatchFiles/Mac"
sh "${buildToolPath}/GenerateProjectFiles.sh" -project="${kk}/ProjectName.uproject"
sh "${enginePath}Build/BatchFiles/RunUAT.sh" BuildCookRun -nocompileeditor -nop4 -project="${projectPath}/ProjectName.uproject" -cook -clean -stage -archive -archivedirectory="${projectPath}/Binaries/" -package -clientconfig=Development -ue4exe=UE4Editor -pak -prereqs -nodebuginfo -targetplatform=IOS -build -utf8output

一顿操作猛如虎,结果却依然是失败的,但这次脚本执行报的错跟前面的不一样了,报的错为can not found ProjectName.module,感觉有进步的空间。在尝试在Google搜索了关键的错误信息后,找到一个回答是说参数没带对,不应该带-nocompileeditor的参数,笔者心想“那我去掉这个参数不就万事大吉了吗?“ 于是去掉了这个参数后,再次执行这个脚本,发现还是脚本执行错误,iOS的包还是没能打出来,不过在对比执行前后的工程目录文件里,发现有个关键的变化,虽然想要的包没有打出来,但Binaries目录下出现了一个Mac的文件夹,而这个文件夹跟用UE4的编辑器打开工程时生成的一模一样,看到这里的时候,就心想,有了这个目录不就是相当于用编辑器打开过这个工程了吗?那我再执行一个类似的命令是不是就可以成功了呢?于是修改了下关键的构建脚本:

enginePath="/Users/Shared/Epic Games/UE_4.27/Engine/"
echo "${enginePath}"
projectPath=`pwd`
echo $projectPath
buildToolPath="${enginePath}Build/BatchFiles/Mac"
rm -df "${projectPath}/Binaries/"
sh "${buildToolPath}/GenerateProjectFiles.sh" -project="${kk}/ProjectName.uproject"
echo "GenerateProjectFiles project success*********************************"
sh "${enginePath}Build/BatchFiles/RunUAT.sh" BuildCookRun -nop4 -project="${projectPath}/ProjectName.uproject" -cook -stage -archive -archivedirectory="${projectPath}/Binaries/" -package -clientconfig=Development -ue4exe=UE4Editor -pak -prereqs -nodebuginfo -targetplatform=IOS -build -utf8output
echo "***********************************************************"
sh "${enginePath}Build/BatchFiles/RunUAT.sh" BuildCookRun -nocompileeditor -nop4 -project="${projectPath}/ProjectName.uproject" -cook -clean -stage -archive -archivedirectory="${projectPath}/Binaries/" -package -clientconfig=Development -ue4exe=UE4Editor -pak -prereqs -nodebuginfo -targetplatform=IOS -build -utf8output
echo "********************"

再次执行修改后的脚本,发现可以成功执行,并正常生成了iOSipa包,这个脚本的关键点为:

  • 调用GenerateProjectFiles脚本生成项目的一些依赖文件;
  • BuildCookRun 命令不带-nocompileeditor,执行类似于用编辑器打开工程的编译操作;
  • BuildCookRun 命令带-nocompileeditor,执行构建安装包的操作;

验证发现脚本打出来的包跟用编辑器的文件菜单里的打包选项打出来的包没区别后,就先用这个脚本把项目的自动化跑起来了。但这个脚本虽然可以正常执行,但一直感觉有点怪,毕竟执行了两次BuildCookRun命令,带着这个疑问,笔者又继续踏上了探索自动化编译UE工程的路程(不断在搜索引擎中换搜索关键字,看大家的一些思路)。

在看了很多国内很多类似的水文之后,终于找到了一个真正有价值的英文文章使用UAT自动化部署UE工程,这篇文章指出了自动化部署UE工程的关键步骤:

  • 使用UBT(Unreal Build Tool)工具编译对应工程的Editor;
  • 使用UAT工具编译对应工程,生成对应平台的安装包;

为什么会需要先使用UBT工具去编译对应工程的Editor呢?因为仅仅使用UAT工具去编译工程的话,会因为工程缺少一些关键的依赖而编译失败,而UBT工具会帮忙创建当前UE4工程依赖的链接库,在对应的链接库创建成功后,再去执行工程的编译逻辑。这也解释了前面如果用编辑器打开过UE4工程后,BuildCookRun命令就可以执行成功的的现象,反之则不行。

最终我们的脚本就调整为:

#UE引擎的路径
enginePath="/Users/Shared/Epic Games/UE_4.27/Engine/"
echo "${enginePath}"
projectPath=`pwd`
echo $projectPath
buildToolPath="${enginePath}Build/BatchFiles/Mac"
rm -df "${projectPath}/Binaries/"
#ProjectName为对应工程的名字
sh "${buildToolPath}/Build.sh" ProjectNameEditor Mac Development "${projectPath}/ProjectName.uproject" --WaitMutex
echo "***********************************************************"
sh "${enginePath}Build/BatchFiles/RunUAT.sh" BuildCookRun -nocompileeditor -nop4 -project="${projectPath}/ProjectName.uproject" -cook -clean -stage -archive -archivedirectory="${projectPath}/Binaries/" -package -clientconfig=Development -ue4exe=UE4Editor -pak -prereqs -nodebuginfo -targetplatform=IOS -build -utf8output
echo "********************"
#最终打出来的包在"${projectPath}/Binaries/IOS/"目录下

附录

BuilcCookRun命令的一些参数解析

  • build :执行编译构建
  • tagetplatform:打包的目标平台,如IOS,Android,Mac,Win64等;
  • nodebuginfo:不拷贝调试信息文件到Stage目录,也就是最终打出来的包中不包含调试信息;
  • prereqs: 将所有依赖打包到一起
  • pak:将资源文件打包到pak文件中;
  • clientconfig:构建包的类型:
    • Development
    • Shipping:发布包
  • package :执行打包(Android->apk,iOS->ipa)
  • archivedirectory: 归档目录
  • archive: 将构建结果归档
  • stage :保存构建过程中的中间结果
  • clean: 在构建之前擦除intermediate文件夹,重新完整构建
  • cook: 使用cook资源
  • project: 需要打包的工程
  • nop4 :禁用Perforce功能
  • ForceDebugInfo :在非debug版本中加入debugwwyth

参考

标签:enginePath,入门,工程,BuildCookRun,projectPath,编译,sh,UE4,打包
From: https://www.cnblogs.com/tomato-haha/p/17415876.html

相关文章

  • docker从入门到实践学习笔记【环境ubuntu16.04】【一】
    镜像加速国内从DockerHub拉取镜像有时会遇到困难,此时可以配置镜像加速器。Docker官方和国内很多云服务商都提供了国内加速器服务,例如: Docker官方提供的中国registrymirrorhttps://registry.docker-cn.com七牛云加速器https://reg-mirror.qiniu.com/ 我们以Docker官......
  • docker从入门到实践学习笔记【环境ubuntu16.04】【二】
     目录获取镜像 运行容器列出镜像虚悬镜像中间层镜像 删除本地镜像批量删除镜像  镜像是docker的三大组件之一。Docker运行容器前需要本地存在对应的镜像,如果本地不存在该镜像,Docker会从镜像仓库下载该镜像。 获取镜像 从Docker镜像仓库获取镜像的命令是dockerpull。......
  • docker从入门到实践学习笔记【环境ubuntu16.04】【三】
    目录 新建容器并启动启动已经终止的容器后台运行终止容器进入容器导入和导出容器导出容器导入容器删除容器清理所有终止状态的容器新建容器并启动 dockerrun 例如,下面的命令输出一个“HelloWorld”,之后终止容器 $dockerrunubuntu:14.04/bin/echo'Helloworld'Hellow......
  • docker从入门到实践学习笔记【环境ubuntu16.04】【四】
    目录数据卷创建一个数据卷查看所有数据卷查看指定数据卷的详细信息启动容器的同时挂在数据卷查看容器的信息删除数据卷在容器销毁时自动删除数据卷挂载主机目录作为数据卷挂载一个本地主机文件作为数据卷  数据卷数据卷特性:1.可以在容器之间共享和重用2.对数据卷的修改立马生效3.......
  • 【由浅入深学MySQL】之MySQL索引基础入门
    本系列为:MySQL数据库详解,为千锋教育资深教学老师独家创作致力于为大家讲解清晰MySQL数据库相关知识点,含有丰富的代码案例及讲解。如果感觉对大家有帮助的话,可以【关注】持续追更~文末有本文重点总结,技术类问题,也欢迎大家和我们沟通交流!前言从今天开始本系列内容就带各位小伙......
  • oracle 中的用户、表空间、数据模式光速入门
    oracle中没有limitROWNUM来处理的只能通过嵌套来处理SELECT*FROM(SELECTCOMP_LN.GIM_RENKOU.LASTUPTIMEFROMCOMP_LN.GIM_RENKOUORDERBYCOMP_LN.GIM_RENKOU.LASTUPTIMEDESC)WHEREROWNUM=1oracle首先连接的时候分为servicename和SID(SystemIdentifi......
  • 老杜MyBatis框架从入门到精通(三)使用MyBatis完成CRUD
    mybatis做为目前国内最为流行的开源orm框架,我们平时在使用时会感受到其带来的诸多便利,但是很少去深入分析,mybatis源码代码量不多,功能丰富,是一个很好的学习样例,本系列文章就和大家一起来学习mybatis框架本系列笔记根据动力节点B站上老杜讲的mybatis教程整理~学习地址:https://www......
  • .NET入门相关学习
    今日任务:制作一个可以对数据库增删改的简单信息系统。 利用官方教程做一个简单的学习。制作步骤整理:一、创建ASP.NETCoreWeb应用项目。二、更改Pages/Shared/_Layout.cshtml设置网站页眉、页脚和菜单,用于之后新建功能页面的跳转。1<ulclass="navbar-navflex-grow-......
  • DCC32命令行方式编译delphi工程源码
    本文链接地址:http://blog.csdn.net/sushengmiyan/article/details/10284879作者:苏生米沿 一、首先找到这个可执行文件,熟悉delphi的人应该很容易就找到,打开你安装delphi的目录,如我的路径C:\ProgramFiles\Delphi_2007\bin\DCC32.EXE二、拷贝一份出来,我将其放在了我的测试目录下......
  • “Linux 基础入门(新版)”实验报告 Linux 目录结构及文件基本操作
    Linux目录结构及文件基本操作来Linux目录结构UNIX是以目录为主的,Linux也继承了这一优良特性。Linux是以树形目录结构的形式来构建整个系统的,可以理解为树形目录是一个用户可操作系统的骨架。虽然本质上无论是目录结构还是操作系统内核都是存储在磁盘上的,但从逻辑上来说Linux......