public static void Build() { const string autoBuildBlock = "AutoBuild.Build()"; BuildLogger.OpenBlock(autoBuildBlock); BuildLogger.LogMessage("Invoke PackageImporter explicitly"); PackageAssetPostprocessor.ImportPackages(); BuildLogger.LogMessage("Parsing additional params"); var args = Environment.GetCommandLineArgs(); UnityEditor.BuildOptions buildOptions = BuildOptions.None; for (int i = 0; i < args.Length; i++) { if (args[i] == "+outdir" && args.Length > i + 1) { outDir = args[i + 1]; BuildLogger.LogMessage("outDir: " + outDir); } else if (args[i] == "+configTypeName" && args.Length > i + 1) { configTypeName = args[i + 1]; BuildLogger.LogMessage("configTypeName: " + configTypeName); if (!configTypeName.Equals(configTypeName.Trim())) // to detect 'CR' at the end { BuildLogger.LogWarning("Build configurator type contains whitespaces (+configTypeName length = " + configTypeName.Length + ")!"); } } else if (args[i] == "+buildTag" && args.Length > i + 1) { buildTag = args[i + 1]; BuildLogger.LogMessage("buildTag: " + buildTag); } else if (args[i] == "+configuration" && args.Length > i + 1) //Test = development build; Release = None { if (args[i + 1] == "Test") { buildOptions = BuildOptions.Development; BuildLogger.LogMessage("configuration: Test(Development build)"); } else { BuildLogger.LogMessage("configuration: Release"); } } } // produce Assets/Resources/build_tag.txt if (buildTag != null) { if (!Directory.Exists("Assets/Resources")) { BuildLogger.LogMessage("Creating Assets/Resources"); Directory.CreateDirectory("Assets/Resources"); } BuildLogger.LogMessage(string.Format("Writing Assets/Resources/{0}.txt: {1}", BuildInfo.k_build_tag, buildTag)); Stream file = File.Create(string.Format("Assets/Resources/{0}.txt", BuildInfo.k_build_tag)); StreamWriter sw = new StreamWriter(file); sw.Write(buildTag); sw.Close(); file.Close(); AssetDatabase.Refresh(); } // prepare default build params BuildLogger.LogMessage("Preparing default build params"); List <string> scenesToBuild = GetScenesToBuild(); UnityEditor.BuildTarget buildTarget = BuildTarget.iPhone; BuildLogger.LogMessage("Default scenes to build:"); foreach (string sceneName in scenesToBuild) { BuildLogger.LogMessage('\t' + sceneName); } BuildLogger.LogMessage("Default buildTarget=" + buildTarget.ToString()); BuildLogger.LogMessage("Default buildOptions=" + buildOptions.ToString()); // run custom builder (or fall back to default) Type configType = null; if (configTypeName != null) { configType = Type.GetType(configTypeName); } IBuildConfig buildConfig = null; if (configType != null) { if (configType.GetInterface("IBuildConfig") != null) { ConstructorInfo defaultConstructorInfo = configType.GetConstructor(new Type [0]); if (defaultConstructorInfo != null) { buildConfig = defaultConstructorInfo.Invoke(new object [0]) as IBuildConfig; if (buildConfig != null) { BuildLogger.LogMessage("Using build configurator \"" + buildConfig.ToString() + "\""); } else { BuildLogger.LogWarning("Failed to construct an instance of build configurator type (+configTypeName \"" + configTypeName + "\")"); } } else { BuildLogger.LogWarning("Build configurator type (+configTypeName \"" + configTypeName + "\") does NOT have a default constructor"); } } else { BuildLogger.LogWarning("Build configurator type (+configTypeName \"" + configTypeName + "\") does NOT implement IBuildConfig"); } } else { BuildLogger.LogWarning("Build configurator type NOT found (+configTypeName \"" + configTypeName + "\")"); } if (buildConfig != null) { string block = string.Format("{0}.Build()", buildConfig.GetType().Name); BuildLogger.OpenBlock(block); buildConfig.Build(scenesToBuild, buildTarget, buildOptions); BuildLogger.CloseBlock(block); } else { BuildLogger.LogError("Unable to configure build for " + configTypeName); throw new ApplicationException("Error: unable to configure build for " + configTypeName); } BuildLogger.CloseBlock(autoBuildBlock); }
public static void ImportPackages() { const string packageImporterBlock = "PackageAssetPostprocessor"; BuildLogger.OpenBlock(packageImporterBlock); // HACK: somehow NOT all newly imported assets are passed to OnPostprocessAllAssets // seems like only the ones imported after PackageImporter itself are (not exactly, but definitely not all) // Because of this our only option is to go through Assets/Packages looking for "_PROJECT_ROOT_" // and force their processing string [] specialAttentionDirs = Directory.GetDirectories(specialAttentionFolder, "_PROJECT_ROOT_", SearchOption.AllDirectories); if (DebugOutput) { BuildLogger.LogMessage("DETECTED DIRS TOTAL: " + specialAttentionDirs.Length); foreach (string path in specialAttentionDirs) { BuildLogger.LogMessage("DETECTED DIR: " + path); } } List <string> listToRelocate = new List <string>(); foreach (string dirPath in specialAttentionDirs) { string [] specialAttentionFiles = Directory.GetFiles(dirPath, "*", SearchOption.AllDirectories); if (DebugOutput && ExcessDebugOutput) { foreach (string filePath in specialAttentionFiles) { BuildLogger.LogMessage("DETECTED FILE: " + filePath); } } listToRelocate.AddRange(specialAttentionFiles); } bool isAssetDatabaseRefreshRequired = false; //foreach(string asset in importedAssets) // HACK: insted of processing importedAssets we now are forced to process manually collected set of files foreach (string asset in listToRelocate) { if (!asset.Contains(".svn")) // cut off svn crap { FileInfo fileInfo = new FileInfo(asset); if (!fileInfo.Extension.Equals(".meta")) // cut off Unity meta files { int index = asset.IndexOf(specialFolder); string targetAsset = asset.Substring(index + specialFolder.Length + 1); FileInfo targetFileInfo = new FileInfo(targetAsset); // let's check if the file needs copying bool existanceCheck = (!targetFileInfo.Exists); bool lengthCheck = (targetFileInfo.Exists && (fileInfo.Length != targetFileInfo.Length)); bool timeCheck = (targetFileInfo.Exists && (targetFileInfo.LastWriteTimeUtc.CompareTo(fileInfo.LastWriteTimeUtc) < 0)); if (existanceCheck || lengthCheck || timeCheck) { if (DebugOutput) { BuildLogger.LogMessage( "COPYING FILE(" + existanceCheck + ", " + lengthCheck + ", " + timeCheck + ") " + fileInfo.Name + " FROM " + fileInfo.Directory.FullName + " TO " + targetFileInfo.Directory.FullName); } Directory.CreateDirectory(targetFileInfo.Directory.FullName); File.Copy(asset, targetAsset, true); isAssetDatabaseRefreshRequired = true; } // CheckAndCopyFile (ref isAssetDatabaseRefreshRequired, fileInfo, targetAsset); CheckOtherFolders(asset, isAssetDatabaseRefreshRequired, index); } } } if (isAssetDatabaseRefreshRequired) { AssetDatabase.Refresh(); } }