├── AutoBuild.cs
├── README.md
└── version.ini
/AutoBuild.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using UnityEditor;
3 | using System;
4 | using System.Collections;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Text;
8 | using System.IO;
9 | using System.IO.Compression;
10 | // this uses the Unity port of DotNetZip https://github.com/r2d2rigo/dotnetzip-for-unity
11 | using Ionic.Zip;
12 |
13 | // place in an "Editor" folder in your Assets folder
14 | public class AutoBuild
15 | {
16 | // TODO: turn this into a wizard or something??? whatever
17 |
18 | ///
19 | /// 时间戳格式 用于版本号及压缩包
20 | ///
21 | public static string TIME_FORMAT = "yyyyMMdd";
22 | // public static string TIME_FORMAT = "yyyyMMdd HH:mm:ss";
23 | // public static string ZIP_TIME_FORMAT = "yyyyMMdd HH_mm_ss";
24 | private static string bundleVersion;
25 |
26 |
27 | //MSDN: https://docs.microsoft.com/en-us/dotnet/api/system.io.compression.ziparchive?redirectedfrom=MSDN&view=netframework-4.7.2
28 | // static void Main(string[] args)
29 | // {
30 | // using (FileStream zipToOpen = new FileStream(@"c:\users\exampleuser\release.zip", FileMode.Open))
31 | // {
32 | // using (ZipArchive archive = new ZipArchive(zipToOpen, ZipArchiveMode.Update))
33 | // {
34 | // ZipArchiveEntry readmeEntry = archive.CreateEntry("Readme.txt");
35 | // using (StreamWriter writer = new StreamWriter(readmeEntry.Open()))
36 | // {
37 | // writer.WriteLine("Information about this package.");
38 | // writer.WriteLine("========================");
39 | // }
40 | // }
41 | // }
42 | // }
43 |
44 | [MenuItem("打包/Build Windows64")]
45 | public static void StartWindows()
46 | {
47 | // Get filename.
48 | // string path = EditorUtility.SaveFolderPanel("Build out WINDOWS to...",
49 | // GetProjectFolderPath() + "/Builds/",
50 | // "");
51 | // var filename = path.Split('/'); // do this so I can grab the project folder name
52 | // var buildPath = "D:\\Unity\\Projects\\Builds";
53 | var buildPath = GetProjectFolderPath() + "/Builds/";
54 |
55 | var name = BuildConfig.SchoolName;
56 |
57 | var appDir = buildPath + name;
58 |
59 | Debug.Log("Start building at "+appDir);
60 |
61 |
62 | PreBuild(buildPath, appDir);
63 | BuildPlayer ( BuildTarget.StandaloneWindows64, name, buildPath );//BuildTarget.StandaloneWindows
64 | }
65 |
66 | static void DeleteAll(string path)
67 | {
68 | if (!Directory.Exists(path))
69 | {
70 | return;
71 | }
72 |
73 | //删除所有文件
74 | foreach (var file in Directory.GetFiles(path))
75 | {
76 | // //保留版本信息
77 | // if (file.Contains("version.ini"))
78 | // {
79 | // continue;
80 | // }
81 |
82 | File.Delete(file);
83 | }
84 |
85 | //递归删除所有文件夹
86 | foreach (var subDir in Directory.GetDirectories(path))
87 | {
88 | // //保留msc文件夹
89 | // if (subDir.Contains("msc"))
90 | // {
91 | // continue;
92 | // }
93 |
94 | DeleteAll(subDir);
95 | Directory.Delete(subDir);
96 | }
97 | }
98 |
99 | ///
100 | /// 删除之前的内容
101 | ///
102 | ///
103 | private static void PreBuild(string buildDir, string appDir)
104 | {
105 | if (!Directory.Exists(buildDir))
106 | {
107 | Directory.CreateDirectory(buildDir);
108 | }
109 | if (!Directory.Exists(appDir))
110 | {
111 | Directory.CreateDirectory(appDir);
112 | }
113 |
114 | // Debug.Log("【AutoBuild】"+buildDir);
115 | // Debug.Log("【AutoBuild】"+appDir);
116 |
117 | DeleteAll(appDir);
118 |
119 | // WriteVersion(appDir);
120 | IncreaseVersion();
121 |
122 | CopyMsc(appDir);
123 | }
124 |
125 | private static void IncreaseVersion()
126 | {
127 | var oldVersion = PlayerSettings.bundleVersion;
128 | Debug.Log("【AutoBuild】当前版本:"+oldVersion);
129 | float oldVersionCode = float.Parse(oldVersion.Split('_')[0].Replace("v",""));
130 | float newVersionCode = oldVersionCode + 0.1f;
131 | bundleVersion = string.Format("v{0}_{1}", newVersionCode, DateTime.Now.ToString(TIME_FORMAT));
132 | PlayerSettings.bundleVersion = bundleVersion;
133 | Debug.Log("【AutoBuild】最新版本:"+bundleVersion);
134 | }
135 |
136 | ///
137 | /// 拷贝msc资源文件 讯飞语音
138 | ///
139 | ///
140 | private static void CopyMsc(string appDir)
141 | {
142 | string sourceDirectory = GetProjectFolderPath()+"/msc";
143 | string targetDirectory = appDir+"/msc";
144 |
145 | DirectoryInfo diSource = new DirectoryInfo(sourceDirectory);
146 | DirectoryInfo diTarget = new DirectoryInfo(targetDirectory);
147 |
148 | CopyAll(diSource, diTarget);
149 | }
150 |
151 | public static void CopyAll(DirectoryInfo source, DirectoryInfo target)
152 | {
153 | if (source.FullName.ToLower() == target.FullName.ToLower())
154 | {
155 | return;
156 | }
157 |
158 | // Check if the target directory exists, if not, create it.
159 | if (Directory.Exists(target.FullName) == false)
160 | {
161 | Directory.CreateDirectory(target.FullName);
162 | }
163 |
164 | // Copy each file into it's new directory.
165 | foreach (FileInfo fi in source.GetFiles())
166 | {
167 | // Debug.Log(string.Format(@"Copying {0}\{1}", target.FullName, fi.Name));
168 | fi.CopyTo(Path.Combine(target.ToString(), fi.Name), true);
169 | }
170 |
171 | // Copy each subdirectory using recursion.
172 | foreach (DirectoryInfo diSourceSubDir in source.GetDirectories())
173 | {
174 | DirectoryInfo nextTargetSubDir =
175 | target.CreateSubdirectory(diSourceSubDir.Name);
176 | CopyAll(diSourceSubDir, nextTargetSubDir);
177 | }
178 | }
179 |
180 | ///
181 | /// 自动写入版本信息
182 | ///
183 | ///
184 | private static void WriteVersion(string dstPath)
185 | {
186 | dstPath += "/version.ini";
187 | var srcPath = Application.dataPath + "/Plugins/version.ini";
188 | // Debug.Log("【BuildRadiator】" + srcPath);
189 | // Debug.Log("【BuildRadiator】" + dstPath);
190 | // Debug.Log("【AutoBuild】" + File.Exists(srcPath) + "," + File.Exists(dstPath));
191 |
192 |
193 | //1.读旧版本信息
194 | string oldVersion;
195 | using (StreamReader sr = new StreamReader(srcPath))
196 | {
197 | oldVersion = sr.ReadToEnd();
198 | }
199 |
200 | //2.更新版本号,写时间戳
201 | string newVersion;
202 | using (StreamWriter sw = new StreamWriter(srcPath, false))
203 | {
204 | int oldVersionCode = int.Parse(oldVersion.Split(',')[0]);
205 | var newVersionCode = oldVersionCode + 1;
206 | newVersion =
207 | newVersionCode + ", BuildTime: " + DateTime.Now.ToString(TIME_FORMAT);
208 | sw.WriteLine(newVersion);
209 | }
210 |
211 | //3.同步到打包路径
212 | // if (!File.Exists(dstPath))
213 | // {
214 | // File.CreateText(dstPath);
215 | // }
216 | using (StreamWriter sw = new StreamWriter(dstPath, false))
217 | {
218 | sw.WriteLine(newVersion);
219 | }
220 | }
221 |
222 |
223 | // [MenuItem("BuildRadiator/Build Windows + Mac OSX + Linux")]
224 | public static void StartAll()
225 | {
226 | // Get filename.
227 | string path = EditorUtility.SaveFolderPanel("Build out ALL STANDALONES to...",
228 | GetProjectFolderPath() + "/Builds/",
229 | "");
230 | var filename = path.Split('/'); // do this so I can grab the project folder name
231 | // BuildPlayer ( BuildTarget.StandaloneOSXUniversal, filename[filename.Length-1], path + "/" );
232 | BuildPlayer(BuildTarget.StandaloneLinuxUniversal, filename[filename.Length - 1],
233 | path + "/");
234 | BuildPlayer(BuildTarget.StandaloneWindows64, filename[filename.Length - 1], path + "/");
235 | }
236 |
237 | // this is the main player builder function
238 | static void BuildPlayer(BuildTarget buildTarget, string filename, string path)
239 | {
240 | string fileExtension = "";
241 | string dataPath = "";
242 | string modifier = "";
243 |
244 | // configure path variables based on the platform we're targeting
245 | switch (buildTarget)
246 | {
247 | case BuildTarget.StandaloneWindows:
248 | case BuildTarget.StandaloneWindows64:
249 | // modifier = "_windows";
250 | fileExtension = ".exe";
251 | dataPath = "_Data/";
252 | break;
253 | case BuildTarget.StandaloneOSXIntel:
254 | case BuildTarget.StandaloneOSXIntel64:
255 | // case BuildTarget.StandaloneOSXUniversal:
256 | // modifier = "_mac-osx";
257 | // fileExtension = ".app";
258 | // dataPath = fileExtension + "/Contents/";
259 | // break;
260 | case BuildTarget.StandaloneLinux:
261 | case BuildTarget.StandaloneLinux64:
262 | case BuildTarget.StandaloneLinuxUniversal:
263 | modifier = "_linux";
264 | dataPath = "_Data/";
265 | switch (buildTarget)
266 | {
267 | case BuildTarget.StandaloneLinux:
268 | fileExtension = ".x86";
269 | break;
270 | case BuildTarget.StandaloneLinux64:
271 | fileExtension = ".x64";
272 | break;
273 | case BuildTarget.StandaloneLinuxUniversal:
274 | fileExtension = ".x86_64";
275 | break;
276 | }
277 |
278 | break;
279 | }
280 |
281 | // Debug.Log("====== BuildPlayer: " + buildTarget.ToString() + " at " + path + filename);
282 | EditorUserBuildSettings.SwitchActiveBuildTarget(buildTarget);
283 |
284 | // build out the player
285 | string buildPath = path + filename + modifier + "/";
286 | // Debug.Log("buildpath: " + buildPath);
287 | string playerPath = buildPath + filename + modifier + fileExtension;
288 | // Debug.Log("playerpath: " + playerPath);
289 | BuildPipeline.BuildPlayer(GetScenePaths(), playerPath, buildTarget,
290 | buildTarget == BuildTarget.StandaloneWindows64
291 | ? BuildOptions.ShowBuiltPlayer
292 | : BuildOptions.None);
293 |
294 | // Copy files over into builds
295 | string fullDataPath = buildPath + filename + modifier + dataPath;
296 | // Debug.Log("fullDataPath: " + fullDataPath);
297 | // CopyFromProjectAssets( fullDataPath, "languages"); // language text files that Radiator uses
298 | // copy over readme
299 |
300 | // string zipTime = DateTime.Now.ToString(ZIP_TIME_FORMAT);
301 | // ZIP everything
302 | // var zipPath = path + "HahaRobotCoach.zip";
303 | var zipPath = path + BuildConfig.SchoolName + modifier + "_" + bundleVersion + ".zip";
304 | Debug.Log("Build finished at "+buildPath);
305 | CompressDirectory(buildPath, zipPath);
306 | }
307 |
308 | // from http://wiki.unity3d.com/index.php?title=AutoBuilder
309 | static string[] GetScenePaths()
310 | {
311 | string[] scenes = new string[EditorBuildSettings.scenes.Length];
312 | for (int i = 0; i < scenes.Length; i++)
313 | {
314 | scenes[i] = EditorBuildSettings.scenes[i].path;
315 | }
316 |
317 | return scenes;
318 | }
319 |
320 | static string GetProjectName()
321 | {
322 | string[] s = Application.dataPath.Split('/');
323 | return s[s.Length - 2];
324 | }
325 |
326 | static string GetProjectFolderPath()
327 | {
328 | var s = Application.dataPath;
329 | s = s.Substring(0,s.Length - 7); // remove "Assets/"
330 | return s;
331 | }
332 |
333 | // copies over files from somewhere in my project folder to my standalone build's path
334 | // do not put a "/" at beginning of assetsFolderName
335 | static void CopyFromProjectAssets(string fullDataPath, string assetsFolderPath,
336 | bool deleteMetaFiles = true)
337 | {
338 | // Debug.Log("CopyFromProjectAssets: copying over " + assetsFolderPath);
339 | FileUtil.ReplaceDirectory(Application.dataPath + "/" + assetsFolderPath,
340 | fullDataPath + assetsFolderPath); // copy over languages
341 |
342 | // delete all meta files
343 | if (deleteMetaFiles)
344 | {
345 | var metaFiles = Directory.GetFiles(fullDataPath + assetsFolderPath, "*.meta",
346 | SearchOption.AllDirectories);
347 | foreach (var meta in metaFiles)
348 | {
349 | FileUtil.DeleteFileOrDirectory(meta);
350 | }
351 | }
352 | }
353 |
354 | // compress the folder into a ZIP file, uses https://github.com/r2d2rigo/dotnetzip-for-unity
355 | static void CompressDirectory(string directory, string zipFileOutputPath)
356 | {
357 | // Debug.Log("Attempting to compress " + directory + " into " + zipFileOutputPath);
358 | // display fake percentage, I can't get zip.SaveProgress event handler to work for some reason, whatever
359 | EditorUtility.DisplayProgressBar("COMPRESSING... please wait", zipFileOutputPath, 0.38f);
360 | using (ZipFile zip = new ZipFile())
361 | {
362 | zip.ParallelDeflateThreshold =
363 | -1; // DotNetZip bugfix that corrupts DLLs / binaries http://stackoverflow.com/questions/15337186/dotnetzip-badreadexception-on-extract
364 | zip.AddDirectory(directory);
365 | zip.Save(zipFileOutputPath);
366 | }
367 |
368 | EditorUtility.ClearProgressBar();
369 |
370 | Debug.Log("Compress finished at " + zipFileOutputPath);
371 |
372 | }
373 | }
374 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # UnityAutoBuild
2 | UnityAutoBuild = Build + Zip + Version Control
3 |
--------------------------------------------------------------------------------
/version.ini:
--------------------------------------------------------------------------------
1 | 24, BuildTime: 20190125 11:45:10
2 |
--------------------------------------------------------------------------------