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); }
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); }
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); }