Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
        }
Beispiel #4
0
        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();
            }
        }
Beispiel #5
0
        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);
        }
Beispiel #9
0
        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);
                }
            }
        }
Beispiel #10
0
        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);
        }
Beispiel #11
0
        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);
                }
            }
        }
Beispiel #12
0
        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);
            }
        }
Beispiel #13
0
        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);
            }
        }
Beispiel #14
0
        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]);
                }
            }
        }
Beispiel #15
0
        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);
            }
        }
Beispiel #16
0
        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);
            }
        }
Beispiel #17
0
        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);
            }
        }
Beispiel #18
0
        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));
        }