public static AssetReferenceDatabase GetDatabase() { if (s_database == null) { if (!Load()) { // Create vanilla db s_database = ScriptableObject.CreateInstance <AssetReferenceDatabase>(); s_database.m_assets = new List <AssetReference>(); s_database.m_dictionary = new Dictionary <string, AssetReference> (); s_database.m_version = DB_VERSION; var DBDir = DataModel.Version2.Settings.Path.TemporalSettingFilePath; if (!Directory.Exists(DBDir)) { Directory.CreateDirectory(DBDir); } AssetDatabase.CreateAsset(s_database, Model.Settings.Path.DatabasePath); } } return(s_database); }
void Load(BuildTarget target, Model.NodeData node, IEnumerable <Model.ConnectionData> connectionsToOutput, PerformGraph.Output Output) { if (connectionsToOutput == null || Output == null) { return; } var outputSource = new List <AssetReference>(); var loadPath = GetLoadPath(target); var targetFiles = AssetDatabase.FindAssets("", new string[] { loadPath }); foreach (var assetGuid in targetFiles) { var targetFilePath = AssetDatabase.GUIDToAssetPath(assetGuid); if (!TypeUtility.IsLoadingAsset(targetFilePath)) { continue; } // Skip folders var type = TypeUtility.GetMainAssetTypeAtPath(targetFilePath); if (type == typeof(UnityEditor.DefaultAsset) && AssetDatabase.IsValidFolder(targetFilePath)) { continue; } var r = AssetReferenceDatabase.GetReference(targetFilePath); if (r == null) { continue; } if (outputSource.Contains(r)) { continue; } if (IsIgnored(targetFilePath)) { continue; } outputSource.Add(r); } var output = new Dictionary <string, List <AssetReference> > { { "0", outputSource } }; var dst = (connectionsToOutput == null || !connectionsToOutput.Any())? null : connectionsToOutput.First(); Output(dst, output); }
public Dictionary <string, List <AssetReference> > ToGroupDictionary() { Dictionary <string, List <AssetReference> > dic = new Dictionary <string, List <AssetReference> >(); foreach (var g in m_groups) { dic [g.name] = g.assets.Select(a => AssetReferenceDatabase.GetReference(a)).ToList(); } return(dic); }
public static void DeleteReference(string relativePath) { AssetReferenceDatabase db = GetDatabase(); if (db.m_dictionary.ContainsKey(relativePath)) { var r = db.m_dictionary[relativePath]; r.InvalidateTypeCache(); db.m_assets.Remove(r); db.m_dictionary.Remove(relativePath); SetDBDirty(); } }
public static void MoveReference(string oldPath, string newPath) { AssetReferenceDatabase db = GetDatabase(); if (db.m_dictionary.ContainsKey(oldPath)) { var r = db.m_dictionary[oldPath]; r.InvalidateTypeCache(); db.m_dictionary.Remove(oldPath); db.m_dictionary[newPath] = r; r.importFrom = newPath; } }
public void Init(Stack <AssetPostprocessorContext> ctxStack) { m_importedAssets = new List <AssetReference>(); m_movedAssets = new List <AssetReference>(); foreach (var path in m_importedAssetPaths) { if (!TypeUtility.IsLoadingAsset(path)) { continue; } bool isAssetFoundInStack = false; foreach (var ctx in ctxStack) { if (ArrayUtility.Contains(ctx.ImportedAssetPaths, path) || ctx.ImportedAssets.Find(a => a.importFrom == path) != null) { isAssetFoundInStack = true; break; } } if (!isAssetFoundInStack) { var a = AssetReferenceDatabase.GetReference(path); m_importedAssets.Add(a); } } for (int i = 0; i < m_movedAssetPaths.Length; ++i) { var movedTo = m_movedAssetPaths [i]; if (!TypeUtility.IsLoadingAsset(movedTo)) { continue; } var a = AssetReferenceDatabase.GetReference(movedTo); m_movedAssets.Add(a); } }
void Load(BuildTarget target, Model.NodeData node, IEnumerable <Model.ConnectionData> connectionsToOutput, PerformGraph.Output Output) { if (connectionsToOutput == null || Output == null) { return; } var cond = m_searchFilter[target]; var outputSource = new List <AssetReference>(); var guids = AssetDatabase.FindAssets(cond); foreach (var guid in guids) { var targetFilePath = AssetDatabase.GUIDToAssetPath(guid); if (!TypeUtility.IsLoadingAsset(targetFilePath)) { continue; } var r = AssetReferenceDatabase.GetReference(targetFilePath); if (r != null) { outputSource.Add(AssetReferenceDatabase.GetReference(targetFilePath)); } } var output = new Dictionary <string, List <AssetReference> > { { "0", outputSource } }; var dst = (connectionsToOutput == null || !connectionsToOutput.Any())? null : connectionsToOutput.First(); Output(dst, output); }
private void HandleAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) { for (int i = 0; i < movedFromAssetPaths.Length; i++) { if (movedFromAssetPaths[i] == DataModel.Version2.Settings.Path.BasePath) { DataModel.Version2.Settings.Path.ResetBasePath(movedAssets[i]); } } foreach (string str in importedAssets) { AssetReferenceDatabase.GetReference(str).InvalidateTypeCache(); } foreach (string str in deletedAssets) { AssetReferenceDatabase.DeleteReference(str); } for (int i = 0; i < movedAssets.Length; i++) { AssetReferenceDatabase.MoveReference(movedFromAssetPaths[i], movedAssets[i]); } var ctx = new AssetPostprocessorContext(importedAssets, deletedAssets, movedAssets, movedFromAssetPaths, m_contexts); if (!ctx.HasValidAssetToPostprocess()) { return; } // if modification happens inside graph, record it. if (m_controllers.Count > 0) { m_ppQueue.Enqueue(ctx); return; } DoPostprocessWithContext(ctx); }
private static AssetReference GetReference(string relativePath, CreateReference creator) { AssetReferenceDatabase db = GetDatabase(); if (db.m_dictionary.ContainsKey(relativePath)) { return(db.m_dictionary[relativePath]); } else { try { AssetReference r = creator(); db.m_assets.Add(r); db.m_dictionary.Add(relativePath, r); AssetReferenceDatabase.SetDBDirty(); return(r); } catch (AssetReferenceException) { // if give asset is invalid, return null return(null); } } }
private static bool Load() { bool loaded = false; try { var dbPath = Model.Settings.Path.DatabasePath; if (File.Exists(dbPath)) { AssetReferenceDatabase db = AssetDatabase.LoadAssetAtPath <AssetReferenceDatabase>(dbPath); if (db != null && db.m_version == DB_VERSION) { db.m_dictionary = new Dictionary <string, AssetReference>(); foreach (var r in db.m_assets) { db.m_dictionary.Add(r.importFrom, r); } s_database = db; loaded = true; } else { if (db != null) { Resources.UnloadAsset(db); } } } } catch (Exception e) { LogUtility.Logger.LogWarning(LogUtility.kTag, e); } return(loaded); }
private static AssetReference GetReference(string relativePath, CreateReference creator) { AssetReferenceDatabase db = GetDatabase(); if (db.m_dictionary.ContainsKey(relativePath)) { return(db.m_dictionary[relativePath]); } else { try { AssetReference r = creator(); db.m_assets.Add(r); db.m_dictionary.Add(relativePath, r); AssetReferenceDatabase.SetDBDirty(); return(r); } catch (AssetReferenceException e) { LogUtility.Logger.LogWarning(LogUtility.kTag, $"AssetReference could not be created: Asset:{e.importFrom} Message:{e.Message}"); // if give asset is invalid, return null return(null); } } }
public override void Prepare(BuildTarget target, Model.NodeData node, IEnumerable <PerformGraph.AssetGroups> incoming, IEnumerable <Model.ConnectionData> connectionsToOutput, PerformGraph.Output Output) { ValidatePrefabBuilder(node, target, incoming, () => throw new NodeException("Output directory not found.", "Create output directory or set a valid directory path.", node), () => throw new NodeException("PrefabBuilder is not configured.", "Configure PrefabBuilder from inspector.", node), () => throw new NodeException("Failed to create PrefabBuilder from settings.", "Fix settings from inspector.", node), (string groupKey) => throw new NodeException( $"Can not create prefab with incoming assets for group {groupKey}.", "Fix group input assets for selected PrefabBuilder.", node), (AssetReference badAsset) => throw new NodeException( $"Can not import incoming asset {badAsset.fileNameAndExtension}.", "", node)); if (incoming == null) { return; } var prefabOutputDir = PrepareOutputDirectory(target, node); var builder = m_instance.Get <IPrefabBuilder>(target); UnityEngine.Assertions.Assert.IsNotNull(builder); Dictionary <string, List <AssetReference> > output = null; if (Output != null) { output = new Dictionary <string, List <AssetReference> >(); } var aggregatedGroups = new Dictionary <string, List <AssetReference> >(); foreach (var ag in incoming) { foreach (var key in ag.assetGroups.Keys) { if (!aggregatedGroups.ContainsKey(key)) { aggregatedGroups[key] = new List <AssetReference>(); } aggregatedGroups[key].AddRange(ag.assetGroups[key].AsEnumerable()); } } foreach (var key in aggregatedGroups.Keys) { var assets = aggregatedGroups[key]; var threshold = PrefabBuilderUtility.GetPrefabBuilderAssetThreshold(m_instance.ClassName); if (threshold < assets.Count) { var guiName = PrefabBuilderUtility.GetPrefabBuilderGUIName(m_instance.ClassName); throw new NodeException( string.Format("Too many assets passed to {0} for group:{1}. {2}'s threshold is set to {4}", guiName, key, guiName, threshold), string.Format("Limit number of assets in a group to {4}", threshold), node); } List <UnityEngine.Object> allAssets = LoadAllAssets(assets); bool canCreatePrefab; if (m_createDescription == null) { m_createDescription = new PrefabCreateDescription(); } try { m_createDescription.Reset(); canCreatePrefab = builder.CanCreatePrefab(key, allAssets, ref m_createDescription); } catch (Exception e) { throw new NodeException(e.Message, "See reason for detail.", node); } if (output != null && canCreatePrefab) { output[key] = new List <AssetReference> () { AssetReferenceDatabase.GetPrefabReference(FileUtility.PathCombine(prefabOutputDir, m_createDescription.prefabName + ".prefab")) }; } UnloadAllAssets(assets); } if (Output != null) { var dst = (connectionsToOutput == null || !connectionsToOutput.Any())? null : connectionsToOutput.First(); Output(dst, output); } }
public override void Prepare(BuildTarget target, Model.NodeData node, IEnumerable <PerformGraph.AssetGroups> incoming, IEnumerable <Model.ConnectionData> connectionsToOutput, PerformGraph.Output Output) { ValidatePrefabBuilder(node, target, incoming, () => { throw new NodeException(node.Name + ":Output directory not found.", node); }, () => { throw new NodeException(node.Name + " :PrefabBuilder is not configured. Please configure from Inspector.", node); }, () => { throw new NodeException(node.Name + " :Failed to create PrefabBuilder from settings. Please fix settings from Inspector.", node); }, (string groupKey) => { throw new NodeException(string.Format("{0} :Can not create prefab with incoming assets for group {1}.", node.Name, groupKey), node); }, (AssetReference badAsset) => { throw new NodeException(string.Format("{0} :Can not import incoming asset {1}.", node.Name, badAsset.fileNameAndExtension), node); } ); if (incoming == null) { return; } var prefabOutputDir = PrepareOutputDirectory(target, node); var builder = m_instance.Get <IPrefabBuilder>(target); UnityEngine.Assertions.Assert.IsNotNull(builder); Dictionary <string, List <AssetReference> > output = null; if (Output != null) { output = new Dictionary <string, List <AssetReference> >(); } var aggregatedGroups = new Dictionary <string, List <AssetReference> >(); foreach (var ag in incoming) { foreach (var key in ag.assetGroups.Keys) { if (!aggregatedGroups.ContainsKey(key)) { aggregatedGroups[key] = new List <AssetReference>(); } aggregatedGroups[key].AddRange(ag.assetGroups[key].AsEnumerable()); } } foreach (var key in aggregatedGroups.Keys) { var assets = aggregatedGroups[key]; var thresold = PrefabBuilderUtility.GetPrefabBuilderAssetThreshold(m_instance.ClassName); if (thresold < assets.Count) { var guiName = PrefabBuilderUtility.GetPrefabBuilderGUIName(m_instance.ClassName); throw new NodeException(string.Format("{0} :Too many assets passed to {1} for group:{2}. {3}'s threshold is set to {4}", node.Name, guiName, key, guiName, thresold), node); } GameObject previousPrefab = null; //TODO List <UnityEngine.Object> allAssets = LoadAllAssets(assets); var prefabFileName = builder.CanCreatePrefab(key, allAssets, previousPrefab); if (output != null && prefabFileName != null) { output[key] = new List <AssetReference> () { AssetReferenceDatabase.GetPrefabReference(FileUtility.PathCombine(prefabOutputDir, prefabFileName + ".prefab")) }; } UnloadAllAssets(assets); } if (Output != null) { var dst = (connectionsToOutput == null || !connectionsToOutput.Any())? null : connectionsToOutput.First(); Output(dst, output); } }
public override void Prepare(BuildTarget target, Model.NodeData node, IEnumerable <PerformGraph.AssetGroups> incoming, IEnumerable <Model.ConnectionData> connectionsToOutput, PerformGraph.Output Output) { ValidateAssetGenerator(node, target, incoming, () => { throw new NodeException("AssetGenerator is not specified.", "Select generator from inspector.", node); }, () => { throw new NodeException("Failed to create AssetGenerator from settings.", "Fix AssetGenerator settings from inspector", node); }, (AssetReference badAsset) => { throw new NodeException($"Generator not create asset from source : Source: {badAsset.importFrom}", "Remove source asset from node input.", node); }, (AssetReference badAsset) => { throw new NodeException($"Can not import incoming asset {badAsset.fileNameAndExtension}.", "Remove source asset from node input.", node); } ); if (incoming == null) { return; } if (connectionsToOutput == null || Output == null) { return; } var allOutput = new Dictionary <string, Dictionary <string, List <AssetReference> > >(); foreach (var outPoints in node.OutputPoints) { allOutput[outPoints.Id] = new Dictionary <string, List <AssetReference> >(); } var defaultOutputCond = connectionsToOutput.Where(c => c.FromNodeConnectionPointId == m_defaultOutputPointId); Model.ConnectionData defaultOutput = null; if (defaultOutputCond.Any()) { defaultOutput = defaultOutputCond.First(); } foreach (var ag in incoming) { if (defaultOutput != null) { Output(defaultOutput, ag.assetGroups); } foreach (var groupKey in ag.assetGroups.Keys) { foreach (var a in ag.assetGroups[groupKey]) { foreach (var entry in m_entries) { var assetOutputDir = PrepareOutputDirectory(target, node, a); var generator = entry.m_instance.Get <IAssetGenerator>(target); UnityEngine.Assertions.Assert.IsNotNull(generator); var newItem = FileUtility.PathCombine(assetOutputDir, GetGeneratorIdForSubPath(target, entry), a.fileName + generator.GetAssetExtension(a)); var output = allOutput[entry.m_id]; if (!output.ContainsKey(groupKey)) { output[groupKey] = new List <AssetReference>(); } output[groupKey].Add(AssetReferenceDatabase.GetReferenceWithType(newItem, generator.GetAssetType(a))); } } } } foreach (var dst in connectionsToOutput) { if (allOutput.ContainsKey(dst.FromNodeConnectionPointId)) { Output(dst, allOutput[dst.FromNodeConnectionPointId]); } } }
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 builder = m_instance.Get <IPrefabBuilder>(target); UnityEngine.Assertions.Assert.IsNotNull(builder); var prefabOutputDir = PrepareOutputDirectory(target, node); Dictionary <string, List <AssetReference> > output = null; if (Output != null) { output = new Dictionary <string, List <AssetReference> >(); } var aggregatedGroups = new Dictionary <string, List <AssetReference> >(); foreach (var ag in incoming) { foreach (var key in ag.assetGroups.Keys) { if (!aggregatedGroups.ContainsKey(key)) { aggregatedGroups[key] = new List <AssetReference>(); } aggregatedGroups[key].AddRange(ag.assetGroups[key].AsEnumerable()); } } var anyPrefabCreated = false; foreach (var key in aggregatedGroups.Keys) { var assets = aggregatedGroups[key]; var allAssets = LoadAllAssets(assets); GameObject previousPrefab = null; //TODO var prefabFileName = builder.CanCreatePrefab(key, allAssets, previousPrefab); var prefabSavePath = FileUtility.PathCombine(prefabOutputDir, prefabFileName + ".prefab"); if (!Directory.Exists(Path.GetDirectoryName(prefabSavePath))) { Directory.CreateDirectory(Path.GetDirectoryName(prefabSavePath)); } if (!File.Exists(prefabSavePath) || PrefabBuildInfo.DoesPrefabNeedRebuilding(prefabOutputDir, this, node, target, key, assets)) { UnityEngine.GameObject obj = builder.CreatePrefab(key, allAssets, previousPrefab); if (obj == null) { throw new AssetGraphException(string.Format("{0} :PrefabBuilder {1} returned null in CreatePrefab() [groupKey:{2}]", node.Name, builder.GetType().FullName, key)); } LogUtility.Logger.LogFormat(LogType.Log, "{0} is (re)creating Prefab:{1} with {2}({3})", node.Name, prefabFileName, PrefabBuilderUtility.GetPrefabBuilderGUIName(m_instance.ClassName), PrefabBuilderUtility.GetPrefabBuilderVersion(m_instance.ClassName)); if (progressFunc != null) { progressFunc(node, string.Format("Creating {0}", prefabFileName), 0.5f); } PrefabUtility.CreatePrefab(prefabSavePath, obj, m_replacePrefabOptions); PrefabBuildInfo.SavePrefabBuildInfo(prefabOutputDir, this, node, target, key, assets); GameObject.DestroyImmediate(obj); anyPrefabCreated = true; AssetProcessEventRecord.GetRecord().LogModify(AssetDatabase.AssetPathToGUID(prefabSavePath)); } UnloadAllAssets(assets); if (anyPrefabCreated) { AssetDatabase.SaveAssets(); } if (output != null) { output[key] = new List <AssetReference> () { AssetReferenceDatabase.GetPrefabReference(prefabSavePath) }; } } if (Output != null) { var dst = (connectionsToOutput == null || !connectionsToOutput.Any())? null : connectionsToOutput.First(); Output(dst, output); } }
public override void Prepare(BuildTarget target, Model.NodeData node, IEnumerable <PerformGraph.AssetGroups> incoming, IEnumerable <Model.ConnectionData> connectionsToOutput, PerformGraph.Output Output) { // BundleBuilder do nothing without incoming connections if (incoming == null) { return; } var bundleOutputDir = PrepareOutputDirectory(target, node, false, true); var bundleNames = incoming.SelectMany(v => v.assetGroups.Keys).Distinct().ToList(); var bundleVariants = new Dictionary <string, List <string> >(); // get all variant name for bundles foreach (var ag in incoming) { foreach (var name in ag.assetGroups.Keys) { if (!bundleVariants.ContainsKey(name)) { bundleVariants[name] = new List <string>(); } var assets = ag.assetGroups[name]; foreach (var a in assets) { var variantName = a.variantName; if (!bundleVariants[name].Contains(variantName)) { bundleVariants[name].Add(variantName); } } } } // add manifest file var manifestName = GetManifestName(target, node, true); bundleNames.Add(manifestName); bundleVariants[manifestName] = new List <string>() { "" }; if (connectionsToOutput != null && Output != null) { UnityEngine.Assertions.Assert.IsTrue(connectionsToOutput.Any()); var outputDict = new Dictionary <string, List <AssetReference> >(); outputDict[key] = new List <AssetReference>(); foreach (var name in bundleNames) { foreach (var v in bundleVariants[name]) { string bundleName = (string.IsNullOrEmpty(v))? name : name + "." + v; AssetReference bundle = AssetReferenceDatabase.GetAssetBundleReference(FileUtility.PathCombine(bundleOutputDir, bundleName)); AssetReference manifest = AssetReferenceDatabase.GetAssetBundleReference(FileUtility.PathCombine(bundleOutputDir, bundleName + Model.Settings.MANIFEST_FOOTER)); outputDict[key].Add(bundle); outputDict[key].Add(manifest); } } var dst = (connectionsToOutput == null || !connectionsToOutput.Any())? null : connectionsToOutput.First(); Output(dst, outputDict); } }
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 builder = m_instance.Get <IPrefabBuilder>(target); Assert.IsNotNull(builder); var prefabOutputDir = PrepareOutputDirectory(target, node); Dictionary <string, List <AssetReference> > output = null; if (Output != null) { output = new Dictionary <string, List <AssetReference> >(); } var aggregatedGroups = new Dictionary <string, List <AssetReference> >(); foreach (var ag in incoming) { foreach (var key in ag.assetGroups.Keys) { if (!aggregatedGroups.ContainsKey(key)) { aggregatedGroups[key] = new List <AssetReference>(); } aggregatedGroups[key].AddRange(ag.assetGroups[key].AsEnumerable()); } } var anyPrefabCreated = false; foreach (var key in aggregatedGroups.Keys) { var assets = aggregatedGroups[key]; var allAssets = LoadAllAssets(assets); try { m_createDescription.Reset(); var canCreatePrefab = builder.CanCreatePrefab(key, allAssets, ref m_createDescription); Assert.IsTrue(canCreatePrefab, "CanCreatePrefab() should not fail at Build phase."); } catch (Exception e) { throw new NodeException(e.Message, "See reason for detail.", node); } var prefabSavePath = FileUtility.PathCombine(prefabOutputDir, m_createDescription.prefabName + ".prefab"); if (!Directory.Exists(Path.GetDirectoryName(prefabSavePath))) { Directory.CreateDirectory(Path.GetDirectoryName(prefabSavePath)); } if (!File.Exists(prefabSavePath) || PrefabBuildInfo.DoesPrefabNeedRebuilding(prefabOutputDir, this, node, target, key, assets, m_createDescription)) { GameObject obj; GameObject previous = null; try { if (m_loadPreviousPrefab && File.Exists(prefabSavePath)) { previous = PrefabUtility.LoadPrefabContents(prefabSavePath); } obj = builder.CreatePrefab(key, allAssets, previous); } catch (Exception e) { throw new NodeException(e.Message, "See reason for detail.", node); } if (obj == null) { throw new AssetGraphException( $"{node.Name} :PrefabBuilder {builder.GetType().FullName} returned null in CreatePrefab() [groupKey:{key}]"); } LogUtility.Logger.LogFormat(LogType.Log, "{0} is (re)creating Prefab:{1} with {2}({3})", node.Name, m_createDescription.prefabName, PrefabBuilderUtility.GetPrefabBuilderGUIName(m_instance.ClassName), PrefabBuilderUtility.GetPrefabBuilderVersion(m_instance.ClassName)); progressFunc?.Invoke(node, $"Creating {m_createDescription.prefabName}", 0.5f); var isPartOfAsset = PrefabUtility.IsPartOfPrefabAsset(obj); PrefabUtility.SaveAsPrefabAsset(obj, prefabSavePath); if (previous != obj && isPartOfAsset) { PrefabUtility.UnloadPrefabContents(obj); } else { Object.DestroyImmediate(obj); } if (previous) { PrefabUtility.UnloadPrefabContents(previous); } PrefabBuildInfo.SavePrefabBuildInfo(prefabOutputDir, this, node, target, key, assets, m_createDescription); anyPrefabCreated = true; AssetProcessEventRecord.GetRecord().LogModify(AssetDatabase.AssetPathToGUID(prefabSavePath)); } UnloadAllAssets(assets); if (anyPrefabCreated) { AssetDatabase.SaveAssets(); } if (output != null) { output[key] = new List <AssetReference> () { AssetReferenceDatabase.GetPrefabReference(prefabSavePath) }; } } if (Output != null) { var dst = (connectionsToOutput == null || !connectionsToOutput.Any())? null : connectionsToOutput.First(); Output(dst, output); } }
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 manifestName = GetManifestName(target, node, false); if (!string.IsNullOrEmpty(m_manifestName [target])) { var projectPath = Directory.GetParent(Application.dataPath).ToString(); var finalManifestName = GetManifestName(target, node, true); if (finalManifestName != manifestName) { var from = FileUtility.PathCombine(projectPath, bundleOutputDir, manifestName); var to = FileUtility.PathCombine(projectPath, bundleOutputDir, finalManifestName); var fromPaths = new string[] { from, from + ".manifest" }; var toPaths = new string[] { to, to + ".manifest" }; for (var i = 0; i < fromPaths.Length; ++i) { if (File.Exists(toPaths[i])) { File.Delete(toPaths[i]); } if (File.Exists(fromPaths[i])) { File.Move(fromPaths[i], toPaths[i]); } else { Debug.LogError("File " + fromPaths[i] + " does not exists! Wanted to copy to " + toPaths[i]); } } manifestName = finalManifestName; } } var generatedFiles = FileUtility.GetAllFilePathsInFolder(bundleOutputDir); // 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)); }