个人感觉Unity打包过程有些不人性化,最近受到频繁的Unity打包的困扰,思考有没有类似于AndroidStudio那样的通过动态脚本对打包,升级版本号,及压缩的管理方案,网上搜了一下,有相关的实现方案,拿来修改之后,最终算是实现了项目的打包管理,打包过程简化了不少,脚本如下,文末贴出下载地址:

using UnityEngine;
using UnityEditor;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.IO.Compression;
// this uses the Unity port of DotNetZip https://github.com/r2d2rigo/dotnetzip-for-unity
using Ionic.Zip;// place in an "Editor" folder in your Assets folder
public class AutoBuild
{// TODO: turn this into a wizard or something??? whatever/// <summary>/// 时间戳格式 用于版本号及压缩包/// </summary>public static string TIME_FORMAT = "yyyyMMdd";
//    public static string TIME_FORMAT = "yyyyMMdd HH:mm:ss";
//    public static string ZIP_TIME_FORMAT = "yyyyMMdd HH_mm_ss";private static string bundleVersion;//MSDN: https://docs.microsoft.com/en-us/dotnet/api/system.io.compression.ziparchive?redirectedfrom=MSDN&view=netframework-4.7.2
//  static void Main(string[] args)
//  {
//      using (FileStream zipToOpen = new FileStream(@"c:\users\exampleuser\release.zip", FileMode.Open))
//      {
//          using (ZipArchive archive = new ZipArchive(zipToOpen, ZipArchiveMode.Update))
//          {
//              ZipArchiveEntry readmeEntry = archive.CreateEntry("Readme.txt");
//              using (StreamWriter writer = new StreamWriter(readmeEntry.Open()))
//              {
//                  writer.WriteLine("Information about this package.");
//                  writer.WriteLine("========================");
//              }
//          }
//      }
//  }[MenuItem("打包/Build Windows64")]public static void StartWindows(){// Get filename.
//      string path = EditorUtility.SaveFolderPanel("Build out WINDOWS to...",
//                                                  GetProjectFolderPath() + "/Builds/",
//                                                  "");
//      var filename = path.Split('/'); // do this so I can grab the project folder name
//        var buildPath = "D:\\Unity\\Projects\\Builds";var buildPath = GetProjectFolderPath() + "/Builds/";var name = BuildConfig.SchoolName;var appDir = buildPath + name;Debug.Log("Start building at "+appDir);PreBuild(buildPath, appDir);BuildPlayer ( BuildTarget.StandaloneWindows64, name, buildPath );//BuildTarget.StandaloneWindows}static void DeleteAll(string path){if (!Directory.Exists(path)){return;}//删除所有文件foreach (var file in Directory.GetFiles(path)){
//            //保留版本信息
//            if (file.Contains("version.ini"))
//            {
//                continue;
//            }File.Delete(file);}//递归删除所有文件夹foreach (var subDir in Directory.GetDirectories(path)){
//            //保留msc文件夹
//            if (subDir.Contains("msc"))
//            {
//                continue;
//            }DeleteAll(subDir);Directory.Delete(subDir);}}/// <summary>/// 删除之前的内容/// </summary>/// <param name="s"></param>private static void PreBuild(string buildDir, string appDir){if (!Directory.Exists(buildDir)){Directory.CreateDirectory(buildDir);}if (!Directory.Exists(appDir)){Directory.CreateDirectory(appDir);}//        Debug.Log("【AutoBuild】"+buildDir);
//        Debug.Log("【AutoBuild】"+appDir);DeleteAll(appDir);//        WriteVersion(appDir);IncreaseVersion();CopyMsc(appDir);}private static void IncreaseVersion(){var oldVersion = PlayerSettings.bundleVersion;Debug.Log("【AutoBuild】当前版本:"+oldVersion);float oldVersionCode = float.Parse(oldVersion.Split('_')[0].Replace("v",""));float newVersionCode = oldVersionCode + 0.1f;bundleVersion = string.Format("v{0}_{1}", newVersionCode, DateTime.Now.ToString(TIME_FORMAT));PlayerSettings.bundleVersion = bundleVersion;Debug.Log("【AutoBuild】最新版本:"+bundleVersion);}/// <summary>/// 拷贝msc资源文件 讯飞语音/// </summary>/// <param name="appDir"></param>private static void CopyMsc(string appDir){string sourceDirectory = GetProjectFolderPath()+"/msc";string targetDirectory = appDir+"/msc";DirectoryInfo diSource = new DirectoryInfo(sourceDirectory);DirectoryInfo diTarget = new DirectoryInfo(targetDirectory);CopyAll(diSource, diTarget);}public static void CopyAll(DirectoryInfo source, DirectoryInfo target){if (source.FullName.ToLower() == target.FullName.ToLower()){return;}// Check if the target directory exists, if not, create it.if (Directory.Exists(target.FullName) == false){Directory.CreateDirectory(target.FullName);}// Copy each file into it's new directory.foreach (FileInfo fi in source.GetFiles()){
//            Debug.Log(string.Format(@"Copying {0}\{1}", target.FullName, fi.Name));fi.CopyTo(Path.Combine(target.ToString(), fi.Name), true);}// Copy each subdirectory using recursion.foreach (DirectoryInfo diSourceSubDir in source.GetDirectories()){DirectoryInfo nextTargetSubDir =target.CreateSubdirectory(diSourceSubDir.Name);CopyAll(diSourceSubDir, nextTargetSubDir);}}/// <summary>/// 自动写入版本信息/// </summary>/// <param name="dstPath"></param>private static void WriteVersion(string dstPath){dstPath += "/version.ini";var srcPath = Application.dataPath + "/Plugins/version.ini";
//        Debug.Log("【BuildRadiator】" + srcPath);
//        Debug.Log("【BuildRadiator】" + dstPath);
//        Debug.Log("【AutoBuild】" + File.Exists(srcPath) + "," + File.Exists(dstPath));//1.读旧版本信息string oldVersion;using (StreamReader sr = new StreamReader(srcPath)){oldVersion = sr.ReadToEnd();}//2.更新版本号,写时间戳string newVersion;using (StreamWriter sw = new StreamWriter(srcPath, false)){int oldVersionCode = int.Parse(oldVersion.Split(',')[0]);var newVersionCode = oldVersionCode + 1;newVersion =newVersionCode + ", BuildTime: " + DateTime.Now.ToString(TIME_FORMAT);sw.WriteLine(newVersion);}//3.同步到打包路径
//        if (!File.Exists(dstPath))
//        {
//            File.CreateText(dstPath);
//        }using (StreamWriter sw = new StreamWriter(dstPath, false)){sw.WriteLine(newVersion);}}//    [MenuItem("BuildRadiator/Build Windows + Mac OSX + Linux")]public static void StartAll(){// Get filename.string path = EditorUtility.SaveFolderPanel("Build out ALL STANDALONES to...",GetProjectFolderPath() + "/Builds/","");var filename = path.Split('/'); // do this so I can grab the project folder name
//      BuildPlayer ( BuildTarget.StandaloneOSXUniversal, filename[filename.Length-1], path + "/" );BuildPlayer(BuildTarget.StandaloneLinuxUniversal, filename[filename.Length - 1],path + "/");BuildPlayer(BuildTarget.StandaloneWindows64, filename[filename.Length - 1], path + "/");}// this is the main player builder functionstatic void BuildPlayer(BuildTarget buildTarget, string filename, string path){string fileExtension = "";string dataPath = "";string modifier = "";// configure path variables based on the platform we're targetingswitch (buildTarget){case BuildTarget.StandaloneWindows:case BuildTarget.StandaloneWindows64:
//          modifier = "_windows";fileExtension = ".exe";dataPath = "_Data/";break;case BuildTarget.StandaloneOSXIntel:case BuildTarget.StandaloneOSXIntel64:
//      case BuildTarget.StandaloneOSXUniversal:
//          modifier = "_mac-osx";
//          fileExtension = ".app";
//          dataPath = fileExtension + "/Contents/";
//          break;case BuildTarget.StandaloneLinux:case BuildTarget.StandaloneLinux64:case BuildTarget.StandaloneLinuxUniversal:modifier = "_linux";dataPath = "_Data/";switch (buildTarget){case BuildTarget.StandaloneLinux:fileExtension = ".x86";break;case BuildTarget.StandaloneLinux64:fileExtension = ".x64";break;case BuildTarget.StandaloneLinuxUniversal:fileExtension = ".x86_64";break;}break;}//        Debug.Log("====== BuildPlayer: " + buildTarget.ToString() + " at " + path + filename);EditorUserBuildSettings.SwitchActiveBuildTarget(buildTarget);// build out the playerstring buildPath = path + filename + modifier + "/";
//        Debug.Log("buildpath: " + buildPath);string playerPath = buildPath + filename + modifier + fileExtension;
//        Debug.Log("playerpath: " + playerPath);BuildPipeline.BuildPlayer(GetScenePaths(), playerPath, buildTarget,buildTarget == BuildTarget.StandaloneWindows64? BuildOptions.ShowBuiltPlayer: BuildOptions.None);// Copy files over into buildsstring fullDataPath = buildPath + filename + modifier + dataPath;
//        Debug.Log("fullDataPath: " + fullDataPath);
//      CopyFromProjectAssets( fullDataPath, "languages"); // language text files that Radiator uses//  copy over readme//        string zipTime = DateTime.Now.ToString(ZIP_TIME_FORMAT);// ZIP everything
//        var zipPath = path + "HahaRobotCoach.zip";var zipPath = path + BuildConfig.SchoolName + modifier + "_" + bundleVersion + ".zip";Debug.Log("Build finished at "+buildPath);CompressDirectory(buildPath, zipPath);}// from http://wiki.unity3d.com/index.php?title=AutoBuilderstatic string[] GetScenePaths(){string[] scenes = new string[EditorBuildSettings.scenes.Length];for (int i = 0; i < scenes.Length; i++){scenes[i] = EditorBuildSettings.scenes[i].path;}return scenes;}static string GetProjectName(){string[] s = Application.dataPath.Split('/');return s[s.Length - 2];}static string GetProjectFolderPath(){var s = Application.dataPath;s = s.Substring(0,s.Length - 7); // remove "Assets/"return s;}// copies over files from somewhere in my project folder to my standalone build's path// do not put a "/" at beginning of assetsFolderNamestatic void CopyFromProjectAssets(string fullDataPath, string assetsFolderPath,bool deleteMetaFiles = true){
//        Debug.Log("CopyFromProjectAssets: copying over " + assetsFolderPath);FileUtil.ReplaceDirectory(Application.dataPath + "/" + assetsFolderPath,fullDataPath + assetsFolderPath); // copy over languages// delete all meta filesif (deleteMetaFiles){var metaFiles = Directory.GetFiles(fullDataPath + assetsFolderPath, "*.meta",SearchOption.AllDirectories);foreach (var meta in metaFiles){FileUtil.DeleteFileOrDirectory(meta);}}}// compress the folder into a ZIP file, uses https://github.com/r2d2rigo/dotnetzip-for-unitystatic void CompressDirectory(string directory, string zipFileOutputPath){
//        Debug.Log("Attempting to compress " + directory + " into " + zipFileOutputPath);// display fake percentage, I can't get zip.SaveProgress event handler to work for some reason, whateverEditorUtility.DisplayProgressBar("COMPRESSING... please wait", zipFileOutputPath, 0.38f);using (ZipFile zip = new ZipFile()){zip.ParallelDeflateThreshold =-1; // DotNetZip bugfix that corrupts DLLs / binaries http://stackoverflow.com/questions/15337186/dotnetzip-badreadexception-on-extractzip.AddDirectory(directory);zip.Save(zipFileOutputPath);}EditorUtility.ClearProgressBar();Debug.Log("Compress finished at " + zipFileOutputPath);}
}

Download on Github https://github.com/BeastwareBoom/UnityAutoBuild
Refering https://gist.github.com/radiatoryang/b65e9c4807a64987aba2

Unity 自动化构建方案:一键实现版本管理与打包、压缩相关推荐

  1. AWS攻略——使用CodeBuild进行自动化构建和部署Lambda(Python)

    Aws Lambda是Amazon推出的"无服务架构"服务.我们只需要简单的上传代码,做些简单的配置,便可以使用.而且它是按运行时间收费,这对于低频访问的服务来说很划算.具体的介绍 ...

  2. 近期总结:generator-web,前端自动化构建的解决方案

    本文结合最近的工作经验,总结出一个较简洁的前端自动化构建方案,主张css和js的模块化,并通过grunt的自动化构建,有效地解决css合并,js合并和图片优化等问题,对于提高前端性能和项目代码质量有一 ...

  3. android 乐固渠道打包,Jenkins奇技淫巧 — Python乐固,多渠道打包篇(Android自动化构建)...

    Jenkins奇技淫巧 - 安装篇(mac) Jenkins奇技淫巧 - 配置篇 Jenkins奇技淫巧 - 安全篇 Jenkins奇技淫巧 - 发送邮件篇 Jenkins奇技淫巧 - 全局变量篇 J ...

  4. 亚信UED前端流程自动化构建工具

    亚信UED前端流程自动化构建工具 亚信UED前端流程自动化构建工具 aiflow 亚信 gulp 项目由亚信CMC UED团队创建,用于解决前端项目构建的流程管理,以及复杂度问题解决. 亚信UED前端 ...

  5. 怎么用python编写个apk_【android】如何利用python做Android项目自动化构建,并一键实现构建结果发送到钉钉通知以及通过二维码下载apk或者其他处理等功能...

    今天我们来谈一谈用python做Android项目自动化构建的过程.我们知道在常规的Android开发过程中,开发人员打包的时候需要在Android Studio当中进行,或者通过gradle命令,但 ...

  6. 前端自动化构建工具介绍

    前端自动化构建工具有: Bower,Gulp,Grunt,node,yeoman... 自动化构建是作为前端工程化中重要的部分,承担着若干需要解决的环节.包括流程管理.版本管理.资源管理.组件化.脚手 ...

  7. 脚本自动定时打开链接_自动化构建系统

    在软件开发过程中,特别是在一些大型多人合作开发的项目中,如何将各个人开发的不同模块集合为一个完整的系统,最终输出一个完整的目标文件,这个过程包括编译,发布,自动化测试等环节.这一过程的完善程度和流畅程 ...

  8. AWS攻略——使用CodeBuild进行自动化构建和部署静态网页

    首先声明下,使用"CodeBuild"部署并不是"正统"的方案,因为AWS提供了"CodeDeploy".如果不希望引入太多基础设施,可以考 ...

  9. 实践Jenkins集成Cobertura自动化构建SpringBoot工程

    在每个系统上线正式发布之前,开发同事对其中功能点进行自测,测试同事根据前期设计的测试用例进行功能测试的都是保障系统可靠稳定运行的重要前提.但是,系统上线后故障还偶有发生,那么如何才能将系统代码质量提高 ...

  10. network setup service启动后自动停止_一个简单的测试环境下的自动化部署方案

    笔者是公司是一个分前后端开发的公司.而笔者是一个普通的后端开发工程师.在和前端工程师协同开发时,为了给前端工程师提供接口,往往要将写好的代码交付并部署到测试环境.因而这导致笔者经常需要打包项目更新到测 ...

最新文章

  1. 设计printf调试宏
  2. boost库下的deadline_timer和steady_timer 区别
  3. 【OpenCV 例程200篇】52. 图像的相关与卷积运算
  4. Spring Cloud入门教程(二):客户端负载均衡(Ribbon)
  5. 补习系列(5)-springboot- restful应用
  6. php 各种排序算法,PHP四种常见排序算法
  7. [转]神奇选股指标问世,每月稳定获利有保障
  8. 高效程序员秘籍(9):快速查找硬盘上的文件和目录
  9. 对于制造企业来说,APS的价值在哪里?
  10. MongoDB 主从复制(主从集群 )
  11. Lambda表达式只是一颗语法糖?
  12. Java之HTTP长连接
  13. 实现div半透明效果
  14. 绿化版IDEA启动时报IF you already have a 64-bit jdk错误的解决
  15. Excel —— 录制宏
  16. 二叉树的中序遍历-python
  17. HashMap常见面试考题
  18. 做人最大的无知,是错把平台当本事(深度好文)
  19. Max and Mex
  20. SQLSERVER 查询指定日期是对应月份的第几周

热门文章

  1. 《运动改造大脑》总结
  2. webserver的使用
  3. [TopCoder] SRM 587 DIV 2, 250p, 500p, 1000p, Solution
  4. google阅读器快捷键
  5. easyui-filebox清空方法扩展自TextBox
  6. ShowWindow函数
  7. 解决scala 2.10.X 无法导入 actors的问题
  8. 使用迅雷等下载工具下载Android SDK快速安装
  9. 安卓桌面软件哪个好_每日提醒软件哪个好?电脑上有什么好用的可以每天提醒的桌面便签软件...
  10. Android 5.1.1 源码目录结构