(轉)基於python腳本,實現Unity全平臺的自動打包

轉載請標明出處: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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章