转载请标明出处: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. fatal: HttpRequestException encountered 解决方法

    fatal: HttpRequestException encountered解决方法   之前在windows下一段时间git push都没什么问题,最近一旦提交就会弹出  无论是push前先将远程 ...

  2. 理解Go Interface

    理解Go Interface 1 概述 Go语言中的接口很特别,而且提供了难以置信的一系列灵活性和抽象性.接口是一个自定义类型,它是一组方法的集合,要有方法为接口类型就被认为是该接口.从定义上来看,接 ...

  3. 【bzoj 4407】于神之怒加强版

    Description 给下N,M,K.求     Input 输入有多组数据,输入数据的第一行两个正整数T,K,代表有T组数据,K的意义如上所示,下面第二行到第T+1行,每行为两个正整数N,M,其意 ...

  4. java面试题总结

    一.http://blog.csdn.net/moneyshi/article/details/50786786 二.http://blog.csdn.net/moneyshi/article/det ...

  5. 从字节码和JVM的角度解析Java核心类String的不可变特性

    1. 前言 最近看到几个有趣的关于Java核心类String的问题. String类是如何实现其不可变的特性的,设计成不可变的好处在哪里. 为什么不推荐使用+号的方式去形成新的字符串,推荐使用Stri ...

  6. 关于table表格 td里内容较多换行的处理方法

    最近在用table的时候由于td内容较多默认换行了,很不美观.于是找到处理方法: 在声明table的时候添加一个样式: <table id="tbOffice" data-r ...

  7. 从YOLOv1到v3的进化之路

    引言:如今基于深度学习的目标检测已经逐渐成为自动驾驶,视频监控,机械加工,智能机器人等领域的核心技术,而现存的大多数精度高的目标检测算法,速度较慢,无法适应工业界对于目标检测实时性的需求,这时YOLO ...

  8. Linux中以单容器部署Nginx+ASP.NET Core

    引言 正如前文提到的,强烈推荐在生产环境中使用反向代理服务器转发请求到Kestrel Http服务器,本文将会实践将Nginx --->ASP.NET Core 部署架构容器化的过程.   Ng ...

  9. ASP.NET Core2.1 你不得不了解的GDPR(Cookie处理)

    前言 时间一晃 ASP.NET Core已经迭代到2.1版本了. 迫不及待的的下载了最新的版本,然后生成了一个模版项目来试试水. ...然后就碰到问题了... 我发现..cookie竟然存不进去了.. ...

  10. 浏览器加载 CommonJS 模块的原理与实现

    就在这个周末,npm 超过了 cpan ,成为地球上最大的软件模块仓库. npm 的模块都是 JavaScript 语言写的,但浏览器用不了,因为不支持 CommonJS 格式.要想让浏览器用上这些模 ...