Unity构建详解(12)——自动构建
【前言】
自动构建是指整个构建流程不需要人工操作,只需要输入启动构建指令即可获取构建结果。实现这样的自动构建需要满足以下条件:
- 支持命令行参数启动
- 我们不可能每次构建时都打开Unity去手动点击构建,必须支持通过命令行启动Unity自动执行构建
- 我们每次构建的需求不同,可能构建Debug、Release或者其他特殊需求的应用,因此Unity需要支持识别命令行输入的不同参数
- 支持工程自动检查
- 我们构建时需要保证不会出现错误,否则中途就构建失败了。错误主要来自于代码和资源,需要在其被提交到主干时就进行自动检查,而不是留在构建时出现构建失败才发现某处代码或资源不对,这是提高构建效率的措施
- 自动检查可以提前发现潜在并帮助解决潜在的问题,减少问题影响域,使得进入游戏包体的问题减少,进而降低人力成本
- 支持应用程序自动构建
- 在Unity中主要是支持iOS自动构建,有两步,一是自动修改xcode工程,二是xcode工程自动执行构建
- 支持构建结果自动上传
【命令行参数启动程序】
我们通常通过点击程序的快捷方式启动程序,而所有程序都可能通过命令行来启动,两者都是调用更底层提供的接口,就好像我们写代码提供一个接口供上层在不同地方调用一样。
以win平台为例,输入exe文件的路径,即可启动程序,例如启动QQ:"C:\Program Files\Tencent\QQ\bin\QQ.exe"。
我们知道main函数是程序的入口,会接受参数输入,我们可以在命令行中输入参数,输入的参数被传递给main函数的args,程序应该读取这些参数并做相应的处理。参数具体是什么由应用程序来定。
命令行输入参数的语法为: -参数名 参数值
不同参数之前没有先后顺序。
Unity提供了命令行参数说明,常用的如下:
- 启动工程
- Unity程序路径 -projectPath Unity工程路径
- 启动工程后执行某个函数
- Unity程序路径 -projectPath Unity工程路径 -executeMethod <NamespaceName.ClassName.MethodName>
- 该函数必须是静态函数且位于Editor文件夹中
- 输出log
- Unity程序路径 -projectPath Unity工程路径 -logfile 输出文件路径
- 执行完命令自动退出
- Unity程序路径 -projectPath Unity工程路径 -quit
- 不打开Unity界面执行
- Unity程序路径 -projectPath Unity工程路径 -batchmode
- 执行时不使用GPU
- Unity程序路径 -projectPath Unity工程路径 -nographics
- 设置构建的目标平台
- -buildTarget ios
- -buildTarget android
- 使用CacheServer
- -EnableCacheServer
- 设置CacheServer端口
- -cacheServerEndpoint 127.0.0.1:10080
- 设置使用的图形API
- -force-gles
- -force-vulkan
- -force-d3d12
更进一步的,我们不可能每次都手动在命令行输入一堆东西,我们需要像点击快捷方式一样,直接运行这些指令,这时就用到bat脚本。bat脚本可以直接问ChatGPT。
@echo off
cd "Unity安装目录路径"
Unity.exe -projectPath "项目路径" -executeMethod MyScript.MyMethod -batchmode -quit
我们可以在启动Unity时调用我们自己的构建函数,即可开始构建。
如果有自定义的参数,可以通过System.Environment.GetCommandLineArgs()获取输入的参数,并做解析。
【工程自动检查】
检查主要分为代码检查和资源检查,可以在每次提交时做一次检查,也可以定时做一次全量检查。
代码检查
可以分为编译检查、规范检查和缺陷检查
编译检查做起来做容易,可以针对每个人的每次提交做检查,主要针对漏提、错提、宏定义等导致的编译不通过情况
规范检查主要是看代码写的符不符合项目规范,虽然理论上有这一条,但实际上基本不会去做,因为每个项目组的规范不一样,要做自定义检查,而且这个检查也不好做,每个人编程习惯有细微差别,强制统一很难实施
缺陷检查很困难,一般会用第三方库做全量检查
通过检查的代码会被合并到主干,进行构建测试,这种频繁的将代码变更合并到主干中,然后自动构建和测试代码的过程叫做持续集成(CI,Continuous Integration)
通过检查后合并到主干一般在互联网开发中的做法,但在游戏中由于资产较重,构建时间很长,一般会直接将程序提交的代码合并到主干,然后再检查,且不会做构建测试
资源检查
凡是游戏内存在的资源,例如策划表、UI Prefab、场景Prefab、Timeline、动作资源、Mesh、各种精度模型、音频、各类配置等,都需要做检查。
可以做一个Unity全资源自动检查的系统,这些可以定时检查,本质上都是命令行启动Unity调用我们的检查方式,在不同的检查方法内实现不同的检查
自动通知
在构建或者检查过程中如果出现报错,我们会将报错信息输出到Log文件中。但是构建和检查一般是在单独的机器中执行的,每次去该机器上找Log文件既繁琐、效率又低,因此需要实现自动通知的功能。
将Log文件发送到某个服务器上进行存储,同时如果检查出错,可以直接将报错信息发送到工作群中的相关人员。
如果办公用的是飞书、钉钉或企业微信,其会提供API让我们去实现自动发消息。
【自动修改xcode工程】
使用Unity提供的PBXProject类,可以在代码中修改xcode工程的配置,示例如下:
public static void OnPostprocessBuild(BuildTarget buildTarget, string path)
{string projPath = path + "/Unity-iPhone.xcodeproj/project.pbxproj";PBXProject proj = new PBXProject();//创建PBXProject对象proj.ReadFromFile(projPath);//获取Targetstring target = proj.TargetGuidByName("Unity-iPhone");//设置自动签名proj.SetBuildProperty(target, "CODE_SIGN_IDENTITY", "Apple Development");proj.SetBuildProperty(target, "CODE_SIGN_STYLE", "Automatic");proj.SetTeamId(target, teamId); //teamId 是对应开发者正好的团队id (在苹果后台可以看到)//添加系统的FrameWorkproj.AddFrameworkToProject(target, "AdSupport.framework", true);proj.AddFrameworkToProject(target, "CoreTelephony.framework", true);proj.AddFrameworkToProject(target, "StoreKit.framework", true); //内购需要 否则 PBXCapabilityType.InAppPurchase会加不上// 设置 BitCodeproj.SetBuildProperty(target, "ENABLE_BITCODE", "false");// 设置 other link flags -ObjCproj.AddBuildProperty (target, "OTHER_LDFLAGS", "-ObjC");// 添加系统的tbd库string filePath = proj.AddFile("usr/lib/" + lib, "Frameworks/" + libPath, PBXSourceTree.Sdk);proj.AddFileToBuild(target, filePath);//添加自定义动态库string defaultLocationInProj = Application.dataPath+"/Editor/Plugins/iOS"; //framework 存放的路径const string coreFrameworkName = "boxjing.framework"; // framework 的文件名string framework = Path.Combine(defaultLocationInProj, coreFrameworkName);string fileGuid = proj.AddFile(framework, "Frameworks/" + coreFrameworkName, PBXSourceTree.Sdk);PBXProjectExtensions.AddFileToEmbedFrameworks(proj, target, fileGuid);proj.SetBuildProperty(target, "LD_RUNPATH_SEARCH_PATHS", "$(inherited) @executable_path/Frameworks");//获取Plist文件string plistPath = path + "/Info.plist";PlistDocument plist = new PlistDocument();plist.ReadFromString(File.ReadAllText(plistPath));PlistElementDict infoDict = plist.root;infoDict.SetString("CFBundleShortVersionString",version); //versioninfoDict.SetString("CFBundleVersion",build); //build//添加权限描述// 权限 根据自己的项目 修改后面的提示文案infoDict.SetString("NSLocationWhenInUseUsageDescription", "为了发现周围的好友,请允许App访问您的地里位置"); //地理位置infoDict.SetString("NSPhotoLibraryUsageDescription", "为了能选择照片进行上传,请允许App访问您的相册"); //相册infoDict.SetString("NSMicrophoneUsageDescription", "为了能够录制声音,请允许App访问您的麦克风权限"); //麦克风//添加URL Schemes白名单,LSApplicationQueriesSchemes是iOS中的一项权限设置,用于确定是否允许应用程序通过特定的URL Scheme与其他应用程序进行交互。URL Scheme是一种用于在应用程序之间传递数据和进行通信的方式PlistElementArray list = plist.root.CreateArray("LSApplicationQueriesSchemes");lsit.AddString("weixin");//同时添加Key和ValuePlistElementDict dic = list.AddDict();dic.SetString("key","value")//获取unityframeworkstring unityFramework = proj.GetUnityFrameworkTargetGuid();
}
xcode自动构建使用官方提供的xcodebuild,这方面的资源很多,就不多说了
【构建结果自动上传】
构建的结果不光是应用程序,还有Log文件,符号表等,这些文件都需要自动上传,而且上传的地方不一样。日常开发是一个环境,发布是另一个环境。
同时,还要将构建结果自动在群里通知。
这里只说了应该做哪些事情,实现起来都不难,就是流程繁琐些。
【定时任务】
python加强
上述用bat脚本实现了自动构建,但是后面还有构建结果自动上传、自动通知,其他各种繁琐细节的操作等,这时候用bat实现就很繁琐,我们可以用Phyton脚本实现,这些都是简单而固定的逻辑,如果不会写可以直接问GPT,下面是示例:
import subprocess
import timedef Init():print("初始化")def run_unity_method(method_name):unity_path = "/path/to/Unity" # Unity的安装路径project_path = "/path/to/UnityProject" # Unity项目的路径command = unity_path + " -batchmode -projectPath " + project_path + " -executeMethod " + method_namesubprocess.call(command, shell=True)def xcode_build():print("xcode构建ipa")def upload_build_result():upload_symbol_table()print("其他结果上传")print("上传构建结果")def upload_symbol_table():# 在这里添加上传符号表的代码print("上传符号表")def auto_notify():print("自动通知")def main():Init()run_unity_method("YourNamespace.YourClassName.YourMethod")time.sleep(1) # 等待1秒#如果是ios平台再加上xcode自动构建的xcode_build()#结果上传upload_build_result()#自动通知auto_notify()if __name__ == "__main__":main()
随后我们只要在命令行中调用Phyton脚本即可
Jenkins加强
实际构建中要输入很多不同的参数,而我们的Phyton脚本中各种参数都固定,我们不可能在命令行中手动输入参数,同时还有一些定时任务等,这需要我们有一个可交互界面,可以用Jenkins
在Jenkins中输出参数,调用Phyton脚本,通过浏览器可以让不同的人都访问到Jenkins。当然Jenkins不止这些功能,但在游戏中其他功能用的不多。
到这一步,我们就完成了持续交付(CD,Continuous Delivery)
JenKins使用介绍
【应用自动安装】
应用自动安装启动是比较高级的功能,一般大型游戏安装下载耗时都在半小时以上,是很耗费时间的,可以在日常构建完成后自动安装启动以提高效率。
Android可以用adb指令通过usb或者wifi安装,同时做个apk监听新应用安装,并发出广播让新应用启动
ios可以使用阿里开源的tidevice
但这两种方式都比较繁琐,统一的解决方案是自己开发一个应用,模拟人工安装过程
【自助自动构建】
一般自动构建是在特定的机器上进行的,如果有人想自己构建验证东西,其会花费很长的时间在构建上。可以做一个自助构建的功能,让其他人借助已有的自动构建系统进行构建。
原理比较简单,先规定一些简单的指令映射自动构建时的参数,随后将这些指令转发给Jenkins即可,
【参考】
利用Unity提供的PBXObject来自动化iOS工程 - 简书
相关文章:
Unity构建详解(12)——自动构建
【前言】 自动构建是指整个构建流程不需要人工操作,只需要输入启动构建指令即可获取构建结果。实现这样的自动构建需要满足以下条件: 支持命令行参数启动 我们不可能每次构建时都打开Unity去手动点击构建,必须支持通过命令行启动Unity自动执…...
中文编程降低了中文环境下编程入门的门槛
近年来,随着编程技术的普及和中文编程环境的日益成熟,越来越多的开发者开始使用中文进行编程。中文编程不仅提高了代码的可读性和理解性,而且在一定程度上降低了中文环境下编程的入门门槛。本文将详细探讨中文编程的优势,以及它如…...

通过内网穿透免费部署我们的springboot+vue项目 实现跟服务器一样的效果
前文讲到通过内网穿透能够实现远程访问个人电脑的静态资源。本文将讲解通过内网穿透实现远程访问本地的项目,实现跟部署到服务器一样的效果:前文链接:通过内网穿透实现远程访问个人电脑资源详细过程(免费)(…...

SMB攻击利用之-mimikatz上传/下载流量数据包逆向分析
SMB协议作为windows环境下最为常见的一种协议,在历史上出现过无数的通过SMB协议进行网络攻击利用的案例,包括针对SMB协议本身以及通过SMB协议实施网络攻击。 本文将介绍一种通过SMB协议的常见利用方式,即向远程主机传输mimikatz,作为我的专栏《SMB攻击流量数据包分析》中的…...
Mysql常见数据类型探索
Mysql常见数据类型探索 数值类型 MySQL 支持所有标准 SQL 数值数据类型。 这些类型包括严格数值数据类型(INTEGER、SMALLINT、DECIMAL 和 NUMERIC),以及近似数值数据类型(FLOAT、REAL 和 DOUBLE PRECISION)。 关键字INT是INTEGER的同义词,关键字DEC是…...

2024 年第四届长三角高校数学建模竞赛赛题B题超详细解题思路+问题一二代码分享
2024年第四届长三角数学建模竞赛B题详细解题思路 赛道B:人工智能范式的物理化学家 长三角分享资料(问题一代码论文思路)链接(18点更新): 链接:https://pan.baidu.com/s/1lteKvIWNZ4v-Gd7oOcg…...

干货速学!1+X电子商务数据分析:电子商务数据分析的流程
电商数据采集API接口 生活中的数据分析 日常工作和生活中处处都有数据分析的存在,比如消费者在购买不同商品前,经常会对儿“性价比”进行简单分析,价格表现为固定的货币数字。性能则具体体现在商品质量、客户收务等客观因素和客户对该商品的需…...

618好物推荐大赏:2024年必囤好物一网打尽,购物攻略助你抢购无忧!
在618购物狂欢节来临之际,我为大家精心挑选了一系列好物,它们不仅品质卓越,更能在日常生活中为我们带来无限便利与乐趣。这里的每一款产品都经过我严格筛选,只为给你最优质的购物体验。让我们一起在这个618,发现生活中…...
【MySQL】基础操作(DDL,DML,DCL,DQL)
安装教程自行搜索,网上有很多 用户名设置为 root密码设置为 123456可以不这样设置,但要记好用户名密码,相关的代码也要自行更改 打开命令提示符程序(winR打开输入cmd回车) 输入:mysql -uroot -p 回车输入密码即可进入命令行环境…...
工厂自动化升级改造(3)-Modbus与MQTT的转换
什么是MQTT,Modbus,见下面文章 工厂自动化升级改造参考(01)--设备通信协议详解及选型-CSDN博客文章浏览阅读608次,点赞9次,收藏6次。>>特点:基于标准的以太网技术,使用TCP/IP协议栈,支持高速数据传输和局域网内的设备通信。>>>特点:跨平台的通信协议,…...

InnoDB 事务处理机制
文章目录 前言1. 事务处理挑战1.1 事务机制处理的问题1.2 并发事务带来的问题 2. InnodDB 和 ACID 模型2.1 Innodb Buffer Pool2.2 Redo log2.3 Undo log2.4 应用案例 3. 隔离级别和锁机制3.1 事务隔离级别3.1.1 READ UNCOMMITTED3.1.2 READ COMMITTED3.1.3 REPEATABLE READ3.1…...

Thymeleaf
替代jsp 功能:服务器渲染(就是将服务器的数据展示在网页上) 1、MVC概念 model 模型 javaBean(User/Book/Order...) View视图 html 服务器的动态数据 Controller控制器 Servlet MVC是在表述层开发运用的一种设计理念。主张把封装数据…...
网络学习(一)|深入了解API网关:定义、功能和关键术语
文章目录 定义主要功能关键术语 定义 API 网关(API Gateway)是一个核心的服务架构组件,用于管理、路由和保护对后端服务的访问。它充当了系统内外的接口,负责接收来自客户端的请求,并将其路由到相应的后端服务&#x…...

基于yolov8+flask搭建一个web版本的网页模型预测系统
测试环境: anaconda3python3.8 torch1.9.0cu111 ultralytics8.2.2 首先我们将训练好的权重放在weights目录下面 并将名字改成yolov8n.pt,如果不想改可以在代码app.py都把路径改过来即可。然后我们打开 python app.py之后看到 我们点击选择文件支持图…...

【北京迅为】《iTOP-3588从零搭建ubuntu环境手册》-第8章 安装编译所需要的依赖包
RK3588是一款低功耗、高性能的处理器,适用于基于arm的PC和Edge计算设备、个人移动互联网设备等数字多媒体应用,RK3588支持8K视频编解码,内置GPU可以完全兼容OpenGLES 1.1、2.0和3.2。RK3588引入了新一代完全基于硬件的最大4800万像素ISP&…...

牛客热题:合并二叉树
牛客热题:二叉树与双向链表> 📟作者主页:慢热的陕西人 🌴专栏链接:力扣刷题日记 📣欢迎各位大佬👍点赞🔥关注🚓收藏,🍉留言 文章目录 牛客热题…...
conda 常用20个命令
conda常用20个命令 这些命令涵盖了Conda环境管理和包管理的常用功能,可帮助你有效地管理Python环境和软件包。 创建环境: conda create --name myenv这个命令用于创建一个名为myenv的新环境。你可以在--name后面指定环境的名称,并在其后加上…...

Git泄露(续)
接上一篇补充 git config --global user.name " " git config --global user.email 邮箱地址 配置用户名和邮箱 git commit 使其处于交互区,没有使用 -m,默认用vim 来编辑和提交信息 输入要提交的内容,然后按ESC建回到命令…...
clickhouse卸载与安装
ClickHouse是一个用于联机分析(OLAP)的列式数据库管理系统(DBMS),来自于俄罗斯本土搜索引擎企业Yandex公司。它是为处理大规模数据集而设计的,并提供高性能和低延迟的查询支持。 注意:此教程的运…...

npm install [Error]
npm install 依赖的时候报错 依赖版本问题的冲突,忽视即可 使用 npm install --legacy-peer-deps...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...
动态 Web 开发技术入门篇
一、HTTP 协议核心 1.1 HTTP 基础 协议全称 :HyperText Transfer Protocol(超文本传输协议) 默认端口 :HTTP 使用 80 端口,HTTPS 使用 443 端口。 请求方法 : GET :用于获取资源,…...

逻辑回归暴力训练预测金融欺诈
简述 「使用逻辑回归暴力预测金融欺诈,并不断增加特征维度持续测试」的做法,体现了一种逐步建模与迭代验证的实验思路,在金融欺诈检测中非常有价值,本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...

手机平板能效生态设计指令EU 2023/1670标准解读
手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读,综合法规核心要求、最新修正及企业合规要点: 一、法规背景与目标 生效与强制时间 发布于2023年8月31日(OJ公报&…...

如何应对敏捷转型中的团队阻力
应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中,明确沟通敏捷转型目的尤为关键,团队成员只有清晰理解转型背后的原因和利益,才能降低对变化的…...