zoukankan      html  css  js  c++  java
  • (转)基于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

  • 相关阅读:
    2016/11/10 kettle概述
    2016/11/07 线程的创建和启动
    python3 pip使用报错
    django建表报错
    django学习
    前端系列
    git使用标准
    我的Python之路
    nginx优化
    python安装包的时候报错
  • 原文地址:https://www.cnblogs.com/wodehao0808/p/15062346.html
Copyright © 2011-2022 走看看