static public void SavePrefabBuildInfo(string buildPath, PrefabBuilder builder, Model.NodeData node, BuildTarget target, string groupKey, List <AssetReference> assets)
        {
            var prefabCacheDir = FileUtility.EnsureCacheDirExists(target, node, PrefabBuilder.kCacheDirName);
            var buildInfoPath  = FileUtility.PathCombine(prefabCacheDir, groupKey + ".asset");

            var version = PrefabBuilderUtility.GetPrefabBuilderVersion(builder.Builder.ClassName);

            var buildInfo = ScriptableObject.CreateInstance <PrefabBuildInfo>();

            buildInfo.Initialize(buildPath, groupKey, builder.Builder.ClassName, builder.Builder[target], version, builder.Options, assets);

            AssetDatabase.CreateAsset(buildInfo, buildInfoPath);
        }
Exemple #2
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);
            }
        }
        static public bool DoesPrefabNeedRebuilding(string buildPath, PrefabBuilder builder, Model.NodeData node, BuildTarget target, string groupKey, List <AssetReference> assets)
        {
            var buildInfo = GetPrefabBuildInfo(builder, node, target, groupKey);

            // need rebuilding if no buildInfo found
            if (buildInfo == null)
            {
                return(true);
            }

            // need rebuilding if build path is changed
            if (buildInfo.m_buildDir != buildPath)
            {
                return(true);
            }

            // need rebuilding if given builder is changed
            if (buildInfo.m_builderClass != builder.Builder.ClassName)
            {
                return(true);
            }

            // need rebuilding if given builder is changed
            if (buildInfo.m_instanceData != builder.Builder[target])
            {
                return(true);
            }

            // need rebuilding if replace prefab option is changed
            if (buildInfo.m_replacePrefabOptions != (int)builder.Options)
            {
                return(true);
            }

            var builderVersion = PrefabBuilderUtility.GetPrefabBuilderVersion(builder.Builder.ClassName);

            // need rebuilding if given builder version is changed
            if (buildInfo.m_prefabBuilderVersion != builderVersion)
            {
                return(true);
            }

            // need rebuilding if given groupKey changed
            if (buildInfo.m_groupKey != groupKey)
            {
                return(true);
            }

            if (!Enumerable.SequenceEqual(
                    buildInfo.m_usedAssets.Select(v => v.importFrom).OrderBy(s => s),
                    assets.Select(v => v.importFrom).OrderBy(s => s)))
            {
                return(true);
            }

            // If any asset is modified from last time, then need rebuilding
            foreach (var usedAsset in buildInfo.m_usedAssets)
            {
                if (usedAsset.IsAssetModifiedFromLastTime)
                {
                    return(true);
                }
            }

            return(false);
        }
Exemple #4
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);
            }
        }
        public static bool DoesPrefabNeedRebuilding(string buildPath, PrefabBuilder builder, Model.NodeData node, BuildTarget target,
                                                    string groupKey, List <AssetReference> assets, PrefabCreateDescription createDescription)
        {
            var buildInfo = GetPrefabBuildInfo(builder, node, target, groupKey);

            // need rebuilding if no buildInfo found
            if (buildInfo == null)
            {
                return(true);
            }

            // need rebuilding if build path is changed
            if (buildInfo.m_buildDir != buildPath)
            {
                return(true);
            }

            // need rebuilding if given builder is changed
            if (buildInfo.m_builderClass != builder.Builder.ClassName)
            {
                return(true);
            }

            // need rebuilding if given builder is changed
            if (buildInfo.m_instanceData != builder.Builder[target])
            {
                return(true);
            }

            var builderVersion = PrefabBuilderUtility.GetPrefabBuilderVersion(builder.Builder.ClassName);

            // need rebuilding if given builder version is changed
            if (buildInfo.m_prefabBuilderVersion != builderVersion)
            {
                return(true);
            }

            // need rebuilding if given groupKey changed
            if (buildInfo.m_groupKey != groupKey)
            {
                return(true);
            }

            var hash1 = MD5.Create();

            assets.ForEach(a => hash1.ComputeHash(System.Text.Encoding.UTF8.GetBytes(a.importFrom)));
            createDescription.additionalAssetPaths.ForEach(path => hash1.ComputeHash(System.Text.Encoding.UTF8.GetBytes(path)));
            if (buildInfo.m_usedAssetsHash != hash1.ToString())
            {
                return(true);
            }

            // If any asset is modified from last time, then need rebuilding
            foreach (var usedAsset in buildInfo.m_usedAssets)
            {
                if (usedAsset.IsAssetModifiedFromLastTime)
                {
                    return(true);
                }
            }

            return(false);
        }