目录
Unity 工具 之 Jenkins 打包自动化工具的下载/安装/基本操作/任务创建执行/Unity打包自动化简单搭建的相关整理
附录:Schedule 中编写规则(周期性触发执行任务)1)格式:MINUTE HOUR DOM MONTH DOW
Unity 工具类,自己整理的一些游戏开发可能用到的模块,单独独立使用,方便游戏开发。
本节介绍,Jenkins 自动化打包工具,包括下载安装,以及基本的操作等,这里简单说明,如果你有更好的方法,欢迎留言交流。
Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能。
主要功能包括:
- 1、持续的软件版本发布/测试项目。
- 2、监控外部调用执行的工作。
这么说比较官方,说白了,它就是一种集承了多种常用的插件于一身的工具平台,通过这个平台你能很方便的管控你的项目!
它的强大之处在于它能直接调用外部的shell指令和bat。
案例操作环境:
官网:Jenkins
下载地址:Jenkins 的安装和设置
1、可以直接到 Jenkins 下载,选择自己的平台下载

2、下载完成后,双击即可安装

这里可能需要对应版本 JDK 环境,没有下载安装对应版本JDK 即可
1、双击安装包,进行安装

2、 选择安装目录
建议不要暗转在 C 盘

3、根据需要选择登陆方式

4、设置并测试端口

5、选择自己的 JDK 安装路径
注意提示的支持的 JDK 版本号,没有的话,可以到jdk 官网下载
JDK 11 下载地址:Java Downloads | Oracle

6、接下来,对应点击操作,安装即可


7、不久,就会安装成功

温馨提示:端口号是之前设置测试的端口号;一些安装软件需要科学上网环境安装
1、输入网址和端口号,登录
例如:http://localhost:5678

2、根据提示复制密码,点击继续即可


3、点击“安装推荐的插件”,根据需要选择也行
注意:这里软件安装需要科学上网环境哈

4、等待安装结束即可

5、插件安装完毕后,根据需要设置创建一个用户

6、设置 Jenkins URL

7、开始使用 Jenkins

1、点击 “开始使用Jenkins”,进入如下界面

1、新建 Item

2、编辑任务名称,选择 Freestyle project,点击确定

3、添加任务描述

4、其他默认,下拉 Build Steps ,选择 Execute Windows batch command

5、编写代码,然后保存即可
echo "Test with no parameter"

6、执行刚才的任务 ,点击 Build Now


7、选择任务,在控制台输出


1、回到 Dashboard ,新建Item

2、输入任务名,确定创建任务

3、添加任务描述,选择 This project is parameterized

4、添加选择参数

5、添加执行命令


6、执行 Build with Parameters



1、创建任务同无参任务创建类似

2、添加任务描述
3、添加任务命令
Test.py 脚本的内容如下:
print('this is a python')


4、Build Now 执行任务

5、如果如图执行任务报错,安装配置一下 python 环境即可
具体参见:https://blog.csdn.net/u014361280/article/details/128725241

有时候我们需要周期性地执行任务,比如每天8点触发一次执行任务,或者每隔30分钟触发一次执行任务。
在Build Triggers(触发器)中勾选Build periodically,
1、创建周期性任务

2、添加描述

3、勾选 Build periodically,编写规则
每分钟执行一次规则:*/1 * * * *

4、添加执行代码


5、Build Now 点击之后,就会每分钟执行一次了


Schedule 中编写规则(周期性触发执行任务)MINUTE HOUR DOM MONTH DOW| 字段 | 说明 | 取值范围 |
|---|---|---|
| MINUTE | 分钟 | 0~59 |
| HOUR | 小时 | 0~23 |
| DOM | 一个月中的第几天 | 1~31 |
| MONTH | 月 | 1~12 |
| DOW | 星期 | 0~7(0和7代表的都是周日) |
2)语法:*:匹配范围内所有值,例:* * * * *M-N:匹配M~N范围内所有值,例:10-30 * * * *M-N/X:在指定M~N范围内每隔X构建一次,例:10-30/5 * * * **/X:整个有效区间内每隔X构建一次,例:*/30 * * * *A,B,...,Z:匹配多个值,例:10,20,30 * * * *
3)关于符号H:
为了在系统中生成定时任务,符号H(代表Hash,后面用散列代替)应该用在可能用到的地方,例如:为十几个日常任务配置0 0 * * *将会在午夜产生较大峰值。相比之下,配置H H * * *仍将每天一次执行每个任务,不是都在同一时刻,可以更好的使用有限资源。
符号H可用于范围,例如,H H(0-7) * * *代表凌晨0:00到 上午7:59一段时间。
符号H在一定范围内可被认为是一个随机值,但实际上它是任务名称的一个散列而不是随机函数。
4)案例:
(1)每30分钟构建一次
H/30 * * * *
(2)每2小时构建一次
H H/2 * * *
(3)每天早上8点构建一次
0 8 * * *
(4)每天的8点,12点,22点,一天构建3次
0 8,12,22 * * *
(5)每前半小时中每隔10分钟构建一次
H(0-29)/10 * * * *
(6)每个工作日从早上9点45分开始到下午4点45分结束这段时间内每间隔2小时的45分钟那一刻构建一次
45 9-16/2 * * 1-5
(7)每月(除了12月)从1号到15号这段时间内某刻构建一次
H H 1,15 1-11 *

1、打开i Unity 创建一个测试工程

2、简单搭建一下场景

3、把场景添加到设置中
1、在 Build Settings 中,手动点击 Build 打包

2、打包成功如图

1、打开 TestJenkins 工程,新建脚本 BuildTool.cs
注意:脚本放在 Editor 文件夹下

using UnityEngine;
using UnityEditor;
public class BuildTools
{
[MenuItem("Build/Build APK")]
public static void BuildApk()
{
BuildPlayerOptions opt = new BuildPlayerOptions();
opt.scenes = new string[] { "Assets/Scenes/SampleScene.unity" };
opt.locationPathName = Application.dataPath + "/../Build/TestJenkens_BatEditorBuild.apk";
opt.target = BuildTarget.Android;
opt.options = BuildOptions.None;
BuildPipeline.BuildPlayer(opt);
Debug.Log("Build App Done!");
}
}
2、编写代码

3、回到 Unity 点击菜单栏 Build-Build APK 进行打包

4、最终打包如下

1、首先可以去官网查看Unity 相关 命令行打包的知识点
网址:Unity - Manual: Command line arguments

2、常用的命令参数解释
-batchmode
在 批处理模式下运行Unity,它不会弹出窗口。当脚本代码在执行过程中发生异常或其他操作失败时Unity将立即退出,并返回代码为1。-quit
命令执行完毕后将退出Unity编辑器。请注意,这可能会导致错误消息被隐藏(但他们将显示在Editor.log文件)-buildWindowsPlayer
构建一个32位的Windows平台的exe(例如:-buildWindowsPlayer path/to/your/build.exe)-buildWindows64Player
构建一个64位的Windows平台的exe(例如:-buildWindows64Player path/to/your/build.exe)-importPackage
导入一个的package,不会显示导入对话框-createProject
根据提供的路径建立一个空项目-projectPath
打开指定路径的项目-logFile
指定输出的日志文件-nographics
当运行在批处理模式,不会初始化显卡设备,不需要GPU参与;但如果你需要执行光照烘焙等操作,则不能使用这个参数,因为它需要GPU运算。-executeMethod
在Unity启动的同时会执行静态方法。也就是说,使用executeMethod我们需要在编辑文件夹有一个脚本并且类里有一个静态函数。-single-instance
在同一时间只允许一个游戏实例运行。如果另一个实例已在运行,然后再次通过-single-instance启动它的话会调节到现有的这个实例。-nolog
不产生输出日志。 通常output_log.txt被写在游戏输出目录下的*_Data文件夹中
3、知道,一个Unity工程只能打开一个实例,所以如果我们已经手动用Unity打开了工程,此时执行下面这个命令是会报错的

Aborting batchmode due to fatal error:
It looks like another Unity instance is running with this project open.
Multiple Unity instances cannot open the same project.
4、所以需要先判断Unity是否在运行中,如果是,则先将旧的Unity实例进程杀掉,对应的bat代码如下
::判断Unity是否运行中
TASKLIST /V /S localhost /U %username%>tmp_process_list.txt
TYPE tmp_process_list.txt |FIND "Unity.exe"
IF ERRORLEVEL 0 (GOTO UNITY_IS_RUNNING)
ELSE (GOTO START_UNITY)
:UNITY_IS_RUNNING
::杀掉Unity
TASKKILL /F /IM Unity.exe
::停1秒
PING 127.0.0.1 -n 1 >NUL
GOTO START_UNITY
:START_UNITY
:: 此处执行Unity打包
另外,我们想要在执行打包时传入一些参数,比如APP名字、版本号等,可以在命令中加上,格式可以自定义,我们只需在后面的C#代码中进行相应的解析即可,例:
--productName:%1 --version:%2
其中%1表示参数1,%2表示参数2,
完整命令如下:
"D:\Program Files\Unity\2021.3.16f1\Editor\Unity.exe" ^
-quit ^
-batchmode ^
-projectPath "E:\Projects\UnityProjects\TestJenkins" ^
-executeMethod BuildTools.BuildApk ^
-logFile "E:\Projects\UnityProjects\TestJenkins\_buildoutput.log"
--productName:%1 ^
--version:%2
5、整合上面的Unity进程判断,最终完整的bat代码如下:
注意:^前有空格
::判断Unity是否运行中
TASKLIST /V /S localhost /U %username%>tmp_process_list.txt
TYPE tmp_process_list.txt |FIND "Unity.exe"
IF ERRORLEVEL 0 (GOTO UNITY_IS_RUNNING)
ELSE (GOTO START_UNITY)
:UNITY_IS_RUNNING
::杀掉Unity
TASKKILL /F /IM Unity.exe
::停1秒
PING 127.0.0.1 -n 1 >NUL
GOTO START_UNITY
:START_UNITY
:: 此处执行Unity打包
"D:\Program Files\Unity\2021.3.16f1\Editor\Unity.exe" ^
-quit ^
-batchmode ^
-projectPath "E:\Projects\UnityProjects\TestJenkins" ^
-executeMethod BuildTools.BuildApk ^
-logFile "E:\Projects\UnityProjects\TestJenkins\_buildoutput.log" ^
--productName:%1 ^
--version:%2
6、打开cmd 切换到 bat 路径,然后输入命令打包
UnityBuild.bat TT 0.1.3,其中 UnityBuild.bat 是批处理脚本,TT 会对应解析为App 名称,0.1.3 是App 版本号

7、输出日志可以找到打包成功的字样

8、其中,BuildTool 中添加对应应用名称和版本号的解析
using UnityEngine;
using UnityEditor;
public class BuildTools
{
[MenuItem("Build/Build APK")]
public static void BuildApk()
{
// 解析命令行参数
string[] args = System.Environment.GetCommandLineArgs();
foreach (var s in args)
{
if (s.Contains("--productName:"))
{
string productName = s.Split(':')[1];
// 设置app名字
PlayerSettings.productName = productName;
}
if (s.Contains("--version:"))
{
string version = s.Split(':')[1];
// 设置版本号
PlayerSettings.bundleVersion = version;
}
}
BuildPlayerOptions opt = new BuildPlayerOptions();
opt.scenes = new string[] { "Assets/Scenes/SampleScene.unity" };
opt.locationPathName = Application.dataPath + "/../Build/TestJenkens_BatEditorBuild.apk";
opt.target = BuildTarget.Android;
opt.options = BuildOptions.None;
BuildPipeline.BuildPlayer(opt);
Debug.Log("Build App Done!");
}
}
1、创建带参数的任务

2、添加代码命令

3、输出对应的应用名称和版本号,开始构建

4、构建成功如图

注意:在 Jenkins 中运行好似有问题,不过这里做个演示记录先

1、把前面的bat 类似转为 python
import os
import sys
import time
# 设置你本地的Unity安装目录
unity_exe = 'D:/Program Files/Unity/2021.3.16f1/Editor/Unity.exe'
# unity工程目录,当前脚本放在unity工程根目录中
project_path = 'E:/Projects/UnityProjects/TestJenkins'
# 日志
log_file = os.getcwd() + '/unity_log.log'
static_func = 'BuildTools.BuildApk'
# 杀掉unity进程
def kill_unity():
os.system('taskkill /IM Unity.exe /F')
def clear_log():
if os.path.exists(log_file):
os.remove(log_file)
# 调用unity中我们封装的静态函数
def call_unity_static_func(func):
kill_unity()
time.sleep(1)
clear_log()
time.sleep(1)
cmd = 'start %s -quit -batchmode -projectPath %s -logFile %s -executeMethod %s --productName:%s --version:%s'%(unity_exe,project_path,log_file,func, sys.argv[1], sys.argv[2])
print('run cmd: ' + cmd)
os.system(cmd)
# 实时监测unity的log, 参数target_log是我们要监测的目标log, 如果检测到了, 则跳出while循环
def monitor_unity_log(target_log):
pos = 0
while True:
if os.path.exists(log_file):
break
else:
time.sleep(0.1)
while True:
fd = open(log_file, 'r', encoding='utf-8')
if 0 != pos:
fd.seek(pos, 0)
while True:
line = fd.readline()
pos = pos + len(line)
if target_log in line:
print(u'监测到unity输出了目标log: ' + target_log)
fd.close()
return
if line.strip():
print(line)
else:
break
fd.close()
if __name__ == '__main__':
call_unity_static_func(static_func)
monitor_unity_log('Build App Done!')
print('done')
2、创建带参数任务

3、添加执行命令

4、Build with Parameters ,输入对应参数,开始构建即可

以管理员身份执行 net stop jenkins
1)以管理员身份运行 cmd

2)输入 net stop jenkins 关闭 Jenkins

3)或者打开 Jenkins 安装目录,在该目录下执行 jenkins.exe stop 也可以关闭服务

以管理员身份执行 net start jenkins
1)以管理员身份运行 cmd

2)输入 net start jenkins 开启 Jenkins

3)或者打开 Jenkins 安装目录,在该目录下执行 jenkins.exe start 也可以开启服务

4)jenkins.exe restart 重新开启服务

1)打开 Jenkins 安装目录,找到 jenkins.xml ,并打开

2)找到 httpPort ,对应就是当前的端口号

3)这里修改为 5578 试试这个端口号

4)重启 Jenkins 服务

5)Jenkins 服务就开始用 5578 这个端口号了

1)点击 Manage Jenkins

2)找到 Manage Users

3)点击 create user 创建新用户

4)对应补全信息,创建即可

5)创建成功

1)账号删除,点击 红色垃圾箱图标即可


2) 账号密码修改,点击蓝色齿轮

3)对应找到 password 选项修改即可


1、【游戏开发进阶】教你Unity通过Jenkins实现自动化打包,打包这种事情就交给策划了(保姆级教程 | 命令行打包 | 自动构建)-网络知识
2、Unity - Manual: Batch mode and built-in coroutine compatibility
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que
有没有办法在这个简单的get方法中添加超时选项?我正在使用法拉第3.3。Faraday.get(url)四处寻找,我只能先发起连接后应用超时选项,然后应用超时选项。或者有什么简单的方法?这就是我现在正在做的:conn=Faraday.newresponse=conn.getdo|req|req.urlurlreq.options.timeout=2#2secondsend 最佳答案 试试这个:conn=Faraday.newdo|conn|conn.options.timeout=20endresponse=conn.get(url
我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b
我意识到这可能是一个非常基本的问题,但我现在已经花了几天时间回过头来解决这个问题,但出于某种原因,Google就是没有帮助我。(我认为部分问题在于我是一个初学者,我不知道该问什么......)我也看过O'Reilly的RubyCookbook和RailsAPI,但我仍然停留在这个问题上.我找到了一些关于多态关系的信息,但它似乎不是我需要的(尽管如果我错了请告诉我)。我正在尝试调整MichaelHartl'stutorial创建一个包含用户、文章和评论的博客应用程序(不使用脚手架)。我希望评论既属于用户又属于文章。我的主要问题是:我不知道如何将当前文章的ID放入评论Controller。
无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD
我的工作要求我为某些测试自动生成电子邮件。我一直在四处寻找,但未能找到可以快速实现的合理解决方案。它需要在outlook而不是其他邮件服务器中,因为我们有一些奇怪的身份验证规则,我们需要保存草稿而不是仅仅发送邮件的选项。显然win32ole可以做到这一点,但我找不到任何相当简单的例子。 最佳答案 假设存储了Outlook凭据并且您设置为自动登录到Outlook,WIN32OLE可以很好地完成此操作:require'win32ole'outlook=WIN32OLE.new('Outlook.Application')message=
?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------
本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01 客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02 数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit