/** * Execute Run operations using current graph */ public void Perform( BuildTarget target, bool isBuild, bool forceVisitAll, Action <Model.NodeData, string, float> updateHandler) { LogUtility.Logger.Log(LogType.Log, (isBuild) ? "---Build BEGIN---" : "---Setup BEGIN---"); m_isBuilding = true; if (isBuild) { AssetBundleBuildReport.ClearReports(); } foreach (var e in m_nodeExceptions) { var errorNode = m_targetGraph.Nodes.Find(n => n.Id == e.Id); // errorNode may not be found if user delete it on graph if (errorNode != null) { LogUtility.Logger.LogFormat(LogType.Log, "[Perform] {0} is marked to revisit due to last error", errorNode.Name); errorNode.NeedsRevisit = true; } } m_nodeExceptions.Clear(); m_lastTarget = target; try { PerformGraph oldGraph = m_performGraph[gIndex]; gIndex = (gIndex + 1) % 2; PerformGraph newGraph = m_performGraph[gIndex]; newGraph.BuildGraphFromSaveData(m_targetGraph, target, oldGraph); PerformGraph.Perform performFunc = (Model.NodeData data, IEnumerable <PerformGraph.AssetGroups> incoming, IEnumerable <Model.ConnectionData> connectionsToOutput, PerformGraph.Output outputFunc) => { DoNodeOperation(target, data, incoming, connectionsToOutput, outputFunc, isBuild, updateHandler); }; newGraph.VisitAll(performFunc, forceVisitAll); if (isBuild && m_nodeExceptions.Count == 0) { Postprocess(); } } catch (NodeException e) { m_nodeExceptions.Add(e); } // Minimize impact of errors happened during node operation catch (Exception e) { LogUtility.Logger.LogException(e); } m_isBuilding = false; LogUtility.Logger.Log(LogType.Log, (isBuild) ? "---Build END---" : "---Setup END---"); }
static public void AddBuildReport(AssetBundleBuildReport r) { Manager.BuildReports.Add(r); }
public override void Build(BuildTarget target, Model.NodeData node, IEnumerable <PerformGraph.AssetGroups> incoming, IEnumerable <Model.ConnectionData> connectionsToOutput, PerformGraph.Output Output, Action <Model.NodeData, string, float> progressFunc) { if (incoming == null) { return; } var aggregatedGroups = new Dictionary <string, List <AssetReference> >(); aggregatedGroups[key] = new List <AssetReference>(); if (progressFunc != null) { progressFunc(node, "Collecting all inputs...", 0f); } foreach (var ag in incoming) { foreach (var name in ag.assetGroups.Keys) { if (!aggregatedGroups.ContainsKey(name)) { aggregatedGroups[name] = new List <AssetReference>(); } aggregatedGroups[name].AddRange(ag.assetGroups[name].AsEnumerable()); } } var bundleOutputDir = PrepareOutputDirectory(target, node, true, true); var bundleNames = aggregatedGroups.Keys.ToList(); var bundleVariants = new Dictionary <string, List <string> >(); if (progressFunc != null) { progressFunc(node, "Building bundle variants map...", 0.2f); } // get all variant name for bundles foreach (var name in aggregatedGroups.Keys) { if (!bundleVariants.ContainsKey(name)) { bundleVariants[name] = new List <string>(); } var assets = aggregatedGroups[name]; foreach (var a in assets) { var variantName = a.variantName; if (!bundleVariants[name].Contains(variantName)) { bundleVariants[name].Add(variantName); } } } int validNames = 0; foreach (var name in bundleNames) { var assets = aggregatedGroups[name]; // we do not build bundle without any asset if (assets.Count > 0) { validNames += bundleVariants[name].Count; } } AssetBundleBuild[] bundleBuild = new AssetBundleBuild[validNames]; List <AssetImporterSetting> importerSetting = null; if (!m_overwriteImporterSetting) { importerSetting = new List <AssetImporterSetting> (); } int bbIndex = 0; foreach (var name in bundleNames) { foreach (var v in bundleVariants[name]) { var assets = aggregatedGroups[name]; if (assets.Count <= 0) { continue; } bundleBuild[bbIndex].assetBundleName = name; bundleBuild[bbIndex].assetBundleVariant = v; bundleBuild[bbIndex].assetNames = assets.Where(x => x.variantName == v).Select(x => x.importFrom).ToArray(); /** * WORKAROND: This will be unnecessary in future version * Unity currently have issue in configuring variant assets using AssetBundleBuild[] that * internal identifier does not match properly unless you configure value in AssetImporter. */ if (!string.IsNullOrEmpty(v)) { foreach (var path in bundleBuild[bbIndex].assetNames) { AssetImporter importer = AssetImporter.GetAtPath(path); if (importer.assetBundleName != name || importer.assetBundleVariant != v) { if (!m_overwriteImporterSetting) { importerSetting.Add(new AssetImporterSetting(importer)); } importer.SetAssetBundleNameAndVariant(name, v); importer.SaveAndReimport(); } } } ++bbIndex; } } if (progressFunc != null) { progressFunc(node, "Building Asset Bundles...", 0.7f); } AssetBundleManifest m = BuildPipeline.BuildAssetBundles(bundleOutputDir, bundleBuild, (BuildAssetBundleOptions)m_enabledBundleOptions[target], target); var output = new Dictionary <string, List <AssetReference> >(); output[key] = new List <AssetReference>(); var generatedFiles = FileUtility.GetAllFilePathsInFolder(bundleOutputDir); var manifestName = GetManifestName(target); // add manifest file bundleVariants.Add(manifestName.ToLower(), new List <string> { null }); foreach (var path in generatedFiles) { var fileName = path.Substring(bundleOutputDir.Length + 1); if (IsFileIntendedItem(fileName, bundleVariants)) { if (fileName == manifestName) { output[key].Add(AssetReferenceDatabase.GetAssetBundleManifestReference(path)); } else { output[key].Add(AssetReferenceDatabase.GetAssetBundleReference(path)); } } } if (Output != null) { var dst = (connectionsToOutput == null || !connectionsToOutput.Any())? null : connectionsToOutput.First(); Output(dst, output); } if (importerSetting != null) { importerSetting.ForEach(i => i.WriteBack()); } AssetBundleBuildReport.AddBuildReport(new AssetBundleBuildReport(node, m, manifestName, bundleBuild, output[key], aggregatedGroups, bundleVariants)); }
private void Export(BuildTarget target, Model.NodeData node, IEnumerable <PerformGraph.AssetGroups> incoming, IEnumerable <Model.ConnectionData> connectionsToOutput, Action <Model.NodeData, string, float> progressFunc) { if (incoming == null) { return; } var exportPath = GetExportPath(m_exportPath[target]); if (m_exportOption[target] == (int)ExportOption.DeleteAndRecreateExportDirectory) { if (Directory.Exists(exportPath)) { FileUtility.DeleteDirectory(exportPath, true); } } if (m_exportOption[target] != (int)ExportOption.ErrorIfNoExportDirectoryFound) { if (!Directory.Exists(exportPath)) { Directory.CreateDirectory(exportPath); } } var report = new ExportReport(node); var cacheFolderDepth = Model.Settings.Path.BundleBuilderCachePath.Split(Model.Settings.UNITY_FOLDER_SEPARATOR).Length; foreach (var ag in incoming) { foreach (var groupKey in ag.assetGroups.Keys) { var inputSources = ag.assetGroups[groupKey]; foreach (var source in inputSources) { var destinationSourcePath = source.importFrom; string destination = null; if (m_flattenDir[target] == 0) { // in bundleBulider, use platform-package folder for export destination. if (destinationSourcePath.StartsWith(Model.Settings.Path.BundleBuilderCachePath)) { var splitted = destinationSourcePath.Split(Model.Settings.UNITY_FOLDER_SEPARATOR); var reducedArray = new string[splitted.Length - cacheFolderDepth]; Array.Copy(splitted, cacheFolderDepth, reducedArray, 0, reducedArray.Length); var fromDepthToEnd = string.Join(Model.Settings.UNITY_FOLDER_SEPARATOR.ToString(), reducedArray); destinationSourcePath = fromDepthToEnd; } destination = FileUtility.PathCombine(exportPath, destinationSourcePath); } else { destination = FileUtility.PathCombine(exportPath, source.fileNameAndExtension); } var parentDir = Directory.GetParent(destination).ToString(); if (!Directory.Exists(parentDir)) { Directory.CreateDirectory(parentDir); } if (File.Exists(destination)) { File.Delete(destination); } if (string.IsNullOrEmpty(source.importFrom)) { report.AddErrorEntry(source.absolutePath, destination, "Source Asset import path is empty; given asset is not imported by Unity."); continue; } try { if (progressFunc != null) { progressFunc(node, string.Format("Copying {0}", source.fileNameAndExtension), 0.5f); } File.Copy(source.importFrom, destination); report.AddExportedEntry(source.importFrom, destination); } catch (Exception e) { report.AddErrorEntry(source.importFrom, destination, e.Message); } source.exportTo = destination; } } } AssetBundleBuildReport.AddExportReport(report); }