轉載請標明出處:http://www.cnblogs.com/zblade/
0. 概述
本文主要針對項目中自動打包過程進行調研,實現用python腳本來打出win/android/ios三個平臺下的遊戲運行包。
1.工具安裝
首先基本的工具需要安裝,Unity, python, 如果需要修改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#腳本來執行打包。
有任何疑問,可以留言討論