转载请标明出处:http://www.cnblogs.com/zblade/

0. 概述

本文主要针对项目中自动打包过程进行调研,实现用python脚本来打出win/android/ios三个平台下的游戏运行包。

1.工具安装

首先基本的工具需要安装,Unity, python, 如果需要修改python脚本,则需要安装一下pycharm,对应的链接:

Download Python

用最新版本即可

pycharm安装

选中最新的即可

pyCharm最新2018激活码(转) - 老董 - 博客园

选用其中的破解补丁激活的方式,可以破解使用到2099年

2.基本流程

1)编写BuildProject相关的c#代码

在unity工程的Editor目录下,编写打包所需要的BuildProject.cs代码,基本操作可以简单归纳为:读取打包脚本的参数,根据参数更新相关设置,根据参数切换到对应的打包平台,执行打包操作。
部分参考代码如下:

    static void BuildTest()
{
PreBuild(); BuildPlayer(); PostBuild();
} //构造之前
static void PreBuild()
{
UpdateParam();
}

2)编写python打包脚本

#!/user/bin/python
#coding = utf-8 import subprocess
import shutil
import os UNITYPATH = "D:/Unity/Editor/Unity.exe"
PROJECTPATH = "D:/WorkProgram/Python/UnityTest/UnityTest"
platform = "android,win,ios" print("begin test") subprocess.call(UNITYPATH + " -quit " + " -batchmode " + " -projectPath " + PROJECTPATH + " -executeMethod BuildProject.BuildTest " + platform) print("end test")

3)执行打包脚本

在pycharm下可以执行执行该打包脚本即可,如果想设置为定时的打包,在windows下可以设置一个定时计划任务,在每天定时执行一次打包脚本即可

3.IOS自动打包

在ios平台上打包,需要将Unity的工程导出为XCode工程,然后在XCode里面进行打ipa包的处理。
如果想要执行自动打包,则需要进行一些特殊的操作,分为以下几个部分:

1)工具准备

在Mac上,首先需要安装一些基本的工具(python/pycharm/XCode默认已经安装):

provisioningFile查看工具:ProfilesManager
查看网上各种操作查看provisioning profiles的操作,这个工具可以实现在XCode里面运行,简易直观的查看
自动打包脚本github示例
这个脚本提供了基本的操作命令,可以在此基础上进一步的编写自己的打包脚本

2)python基本脚本

参考上面的自动打包脚本,测试和修改一些bug(填坑~),得到一个可以基本运行的自动将xcodeproject导出为ipa的运行脚本,保留如下:

#! /usr/bin/python
# coding=utf-8
# -*- coding:utf8 -*- from optparse import OptionParser
import subprocess
import os
import time #unity path and project path
UNITYPATH = "/Applications/Unity/Unity.app/Contents/MacOS/Unity"
PROJECTPATH = "******"
# configuration for iOS build setting
CONFIGURATION = "Release"
SDK = "iphoneos"
PROJECT = "*****"
CACHAPATH = "*****"
TARGET = "****"
SCHEME = "Unity-iPhone"
#桌面上创建出ipa
EXPORT_MAIN_DIRECTORY = "~/Desktop/"
EXPORT_OPTIONS_PLIST = "exportOptions.plist" def buildArchivePath(tempName):
process = subprocess.Popen("pwd", stdout = subprocess.PIPE)
(stdoutdata, stderrdata) = process.communicate()
archiveName = "/%s.xcarchive" %(tempName)
#print("name " + stdoutdata.strip().decode())
archivePath = CACHAPATH + archiveName
return archivePath def cleanArchiveFile(archiveFile):
cleanCmd ="rm -r %s" %(archiveFile)
process = subprocess.Popen(cleanCmd, shell=True)
process.wait()
print("clean archiveFile: %s" %(archiveFile)) def buildExportDirectory(scheme):
dateCmd = 'date "+%Y-%m-%d_%H-%M-%S"'
process = subprocess.Popen(dateCmd, stdout= subprocess.PIPE, shell= True)
(stdoutdata, stderrdata) = process.communicate()
exportDirectory = "%s%s%s" %(EXPORT_MAIN_DIRECTORY, scheme, "-test1")
print("export directory: " + exportDirectory)
return exportDirectory def exportArchive(scheme, archivePath):
exportDirectory = buildExportDirectory(scheme)
exportCmd = "xcodebuild -exportArchive -archivePath %s -exportPath %s -allowProvisioningUpdates -exportOptionsPlist %s" %(archivePath, exportDirectory, EXPORT_OPTIONS_PLIST)
process = subprocess.Popen(exportCmd, shell=True)
(stdoutdata, stderrdata) = process.communicate() signReturnCode = process.returncode
if signReturnCode != 0:
print("export %s failed" %scheme)
return ""
else:
return exportDirectory def buildProject(project, target, output):
archivePath = buildArchivePath(SCHEME)
print("arcivePath: "+ archivePath)
process = subprocess.Popen('replace_provision_config', shell= True)
process.wait() time1 = time.time()
#archiveCmd = 'xcodebuild archive -archivePath %s' + archivePath + ' -scheme ' + "Unity-iPhone" + ' -quiet -configuration %s' + SCHEME
archiveCmd = 'xcodebuild -project %s -scheme %s -configuration %s archive -archivePath %s -destination generic/platform=iOS' %(project, SCHEME, CONFIGURATION, archivePath)
process = subprocess.Popen(archiveCmd, shell= True)
process.wait()
time2= time.time()
print("finish archive cmd, used time: " + str(time2 - time1))
archiveReturnCode = process.returncode;
if archiveReturnCode != 0:
print("archive project %s failed " %project)
cleanArchiveFile(archivePath)
else:
print("begin export archive")
time3 = time.time()
exportDirectory = exportArchive(SCHEME, archivePath)
time4 = time.time()
print("finish export archive, used time: " + str(time4 - time3))
cleanArchiveFile(archivePath)
if exportDirectory != "":
print("export archive success") def showNotification(title, subtitle):
os.system("osascript -e 'display notification \"" + subtitle + "\" with title \"" + title + "\"'") #对xcode工程进行build
def xcbuild():
output = os.path.expanduser("~") + '/Desktop/' + TARGET + '.ipa'
#comments = options.comments
print(output)
buildProject(PROJECT, TARGET, output) #先执行unity的build.buildplayer,导出xcode工程
#在windows平台可以用call调用,但是在Mac下,用Popen执行,不然会报文件无法查找的错误
#在mac平台下,则需要执行popen的操作来执行命令行
def buildProjectResource():
print("先导出mac包")
build = UNITYPATH + ' -quit -batchmode -projectPath ' + PROJECTPATH + ' -executeMethod BuildProject.BuildIOS '
buildCmd = build + "mac"
#subprocess.call(buildCmd)
time1 = time.time()
#process = subprocess.Popen(buildCmd, shell = True)
#process.wait()
time2 = time.time()
print("导出mac所用时间: " + str(time2-time1))
#再导出apk包
print("再导出apk")
buildCmd = build + "android"
time3 = time.time()
#process = subprocess.Popen(buildCmd, shell = True)
#process.wait()
time4= time.time()
print("导出apk所用时间: " + str(time4 - time3))
#再导出ios
print("再导出xcode")
buildCmd = build + "ios"
time5 = time.time()
process = subprocess.Popen(buildCmd, shell = True)
process.wait()
time6 = time.time()
print("导出Xcode工程所用时间: " + str(time6 - time5)) def main():
buildProjectResource()
xcbuild() if __name__ == '__main__':
main()

其中标注为"*****"为你对应的项目的相关路径,可以自行填写。

对应的exportOptions.plist文件为:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>provisioningProfiles</key>
<dict>
<key>com.topjoy.pod1</key>
<string>XC com topjoy pod1 </string>
</dict>
<key>method</key>
<string>development</string>
<key>compileBitcode</key>
<true/>
</dict>
</plist>

3)执行打包脚本

执行打包脚本,目前会在unity导出xcode工程后中断,需要手动点击导出的xcode工程,然后设置signing中的appID,生成对应的provisioning profiles,然后继续执行脚本,可以得到最终的ipa文件,这个可以集合后面的打包工具,实现XCode中的签证设置,最终实现一键打包操作。

4.拓展性

目前只是一个简单的打包脚本,后续针对不同平台会有不同的配置,则需要对应的填充和拓展打包脚本以及对应的c#脚本来执行打包。

有任何疑问,可以留言讨论

参考文章:

iOS自动打包并发布脚本
Xcode9 xcodebuild 命令行打包遇到的坑与解决方案

iOS 自动构建命令——xcodebuild

基于python脚本,实现Unity全平台的自动打包的更多相关文章

  1. 搭建基于python +opencv+Beautifulsoup+Neurolab机器学习平台

    搭建基于python +opencv+Beautifulsoup+Neurolab机器学习平台 By 子敬叔叔 最近在学习麦好的<机器学习实践指南案例应用解析第二版>,在安装学习环境的时候 ...

  2. 基于python脚本的对拍debug

    首先,这是python脚本 import os; for i in range(0,20): print ("Case:"+str(i)); print ("random ...

  3. FreeCAD stp文件基于python脚本操作

    FreeCAD对于3D模型处理这块的东西封装的还是很完善的,所以移植这块的东西还是有必要的! 首先下载FreeCAD编译好的库: https://www.freecadweb.org/wiki/Dow ...

  4. Python脚本控制的WebDriver 常用操作 <一> 启动浏览器

    由于本人的学习定位是基于Selenium+WebDriver+Python+FireFox+Eclipse+Pydev, 所以我的笔记也只和这方面相关. 我打算先学习基于Python脚本WebDriv ...

  5. Python实用案例,Python脚本,Python实现每日更换“必应图片”为“桌面壁纸”

    往期回顾 Python实现自动监测Github项目并打开网页 Python实现文件自动归类 Python实现帮你选择双色球号码 前言: 今天我们就利用python脚本实现每日更换"必应图片& ...

  6. React Native开发中自动打包脚本

    React Native开发中自动打包脚本 在日常的RN开发中,我们避免不了需要将我们编写的代码编译成安装包,然后生成二维码,供需要测试的人员扫描下载.但是对于非原生的开发人员来说,可能不知如何使用X ...

  7. 一行导出所有任意微软SQL server数据脚本-基于Python的微软官方mssql-scripter工具使用全讲解

    文章标题: 一行导出所有任意微软SQL serer数据脚本-基于Python的微软官方mssql-scripter工具使用全讲解 关键字 : mssql-scripter,SQL Server 文章分 ...

  8. 基于python的互联网软件测试开发(自动化测试)-全集合

    基于python的互联网软件测试开发(自动化测试)-全集合 1   关键字 为了便于搜索引擎收录本文,特别将本文的关键字给强调一下: python,互联网,自动化测试,测试开发,接口测试,服务测试,a ...

  9. 【airflow实战系列】 基于 python 的调度和监控工作流的平台

    简介 airflow 是一个使用python语言编写的data pipeline调度和监控工作流的平台.Airflow被Airbnb内部用来创建.监控和调整数据管道.任何工作流都可以在这个使用Pyth ...

随机推荐

  1. CString 转化成 const char* 类型

    写程序的时候经常会遇到无法将“CString”转换为“const char *”的错误,这里我找到了一个解决办法,与大家分享下: CString cs = _T("); ) * ; char ...

  2. 【BZOJ 4031】: [HEOI2015]小Z的房间

    题目大意: 给一个n×m的网格,“.”表示可联通,求该网格可构成的生成树个数在1E9的剩余系中的结果.(n,m<=9) 题解: 忘了删注释WA了两遍…… 直接建图+MartrixTree定理即可 ...

  3. 前端学习笔记之CSS选择器

    阅读目录 一 基本选择器 二 后代选择器.子元素选择器 三 兄弟选择器 四 交集选择器与并集选择器 五 序列选择器 六 属性选择器 七 伪类选择器 八 伪元素选择器 九 CSS三大特性 一 基本选择器 ...

  4. 哎呀,我老大写Bug啦——记一次MessageQueue的优化

    MessageQueue,顾名思义消息队列,在系统开发中也是用的比较多的一个中间件吧.我们这里主要用它来做日志管理和订单管理的,记得老老大(恩,是的,就是老老大,因为他已经跳槽了)还在的时候,当时也是 ...

  5. python接口自动化(二十四)--unittest断言——中(详解)

    简介 上一篇通过简单的案例给小伙伴们介绍了一下unittest断言,这篇我们将通过结合和围绕实际的工作来进行unittest的断言.这里以获取城市天气预报的接口为例,设计了 2 个用例,一个是查询北京 ...

  6. 前端笔记之ES678&Webpack&Babel(上)初识ES678&Babel&let和const&解构&语法

    一.ES版本简介和调试运行方法 1.1 ECMAScript简介 MDN手册:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript JavaS ...

  7. len(x) 击败 x.len(),从内置函数看 Python 的设计思想

    内置函数是 Python 的一大特色,用极简的语法实现很多常用的操作. 它们预先定义在内置命名空间中,开箱即用,所见即所得.Python 被公认是一种新手友好型的语言,这种说法能够成立,内置函数在其中 ...

  8. 论文学习-深度学习目标检测2014至201901综述-Deep Learning for Generic Object Detection A Survey

    目录 写在前面 目标检测任务与挑战 目标检测方法汇总 基础子问题 基于DCNN的特征表示 主干网络(network backbone) Methods For Improving Object Rep ...

  9. VulDeePecker:基于深度学习的脆弱性检测系统

    最近的两款软件,VUDDY和VulPecker,假阴性率高而假阳性率低,用于检测由代码克隆引发的漏洞.而如果用于非代码克隆引起的漏洞则会出现高误报率. 本文使用深度学习处理程序中的代码片段,不应由专家 ...

  10. Webpack系列-第一篇基础杂记

    前言 公司的前端项目基本都是用Webpack来做工程化的,而Webpack虽然只是一个工具,但内部涉及到非常多的知识,之前一直靠CV来解决问题,之知其然不知其所以然,希望这次能整理一下相关的知识点. ...