public void Setup(BuildTarget target, NodeData node, IEnumerable <PerformGraph.AssetGroups> incoming, IEnumerable <ConnectionData> connectionsToOutput, PerformGraph.Output Output) { ValidatePrefabBuilder(node, target, incoming, () => { throw new NodeException(node.Name + " :PrefabBuilder is not configured. Please configure from Inspector.", node.Id); }, () => { throw new NodeException(node.Name + " :Failed to create PrefabBuilder from settings. Please fix settings from Inspector.", node.Id); }, (string groupKey) => { throw new NodeException(string.Format("{0} :Can not create prefab with incoming assets for group {1}.", node.Name, groupKey), node.Id); }, (AssetReference badAsset) => { throw new NodeException(string.Format("{0} :Can not import incoming asset {1}.", node.Name, badAsset.fileNameAndExtension), node.Id); } ); if (incoming == null) { return; } var builder = PrefabBuilderUtility.CreatePrefabBuilder(node, target); UnityEngine.Assertions.Assert.IsNotNull(builder); var prefabOutputDir = FileUtility.EnsurePrefabBuilderCacheDirExists(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()); } } foreach (var key in aggregatedGroups.Keys) { var assets = aggregatedGroups[key]; var thresold = PrefabBuilderUtility.GetPrefabBuilderAssetThreshold(node.ScriptClassName); if (thresold < assets.Count) { var guiName = PrefabBuilderUtility.GetPrefabBuilderGUIName(node.ScriptClassName); 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.Id); } List <UnityEngine.Object> allAssets = LoadAllAssets(aggregatedGroups[key]); var prefabFileName = builder.CanCreatePrefab(key, allAssets); if (output != null && prefabFileName != null) { output[key] = new List <AssetReference> () { AssetReferenceDatabase.GetPrefabReference(FileUtility.PathCombine(prefabOutputDir, prefabFileName + ".prefab")) }; } allAssets.ForEach(o => Resources.UnloadAsset(o)); } if (Output != null) { var dst = (connectionsToOutput == null || !connectionsToOutput.Any())? null : connectionsToOutput.First(); Output(dst, output); } }
private void DoInspectorPrefabBuilderGUI(NodeGUI node) { EditorGUILayout.HelpBox("PrefabBuilder: Create prefab with given assets and script.", MessageType.Info); UpdateNodeName(node); using (new EditorGUILayout.VerticalScope(GUI.skin.box)) { var map = PrefabBuilderUtility.GetAttributeClassNameMap(); if (map.Count > 0) { using (new GUILayout.HorizontalScope()) { GUILayout.Label("PrefabBuilder"); var guiName = PrefabBuilderUtility.GetPrefabBuilderGUIName(node.Data.ScriptClassName); if (GUILayout.Button(guiName, "Popup", GUILayout.MinWidth(150f))) { var builders = map.Keys.ToList(); if (builders.Count > 0) { NodeGUI.ShowTypeNamesMenu(guiName, builders, (string selectedGUIName) => { using (new RecordUndoScope("Change PrefabBuilder class", node, true)) { m_prefabBuilder = PrefabBuilderUtility.CreatePrefabBuilder(selectedGUIName); if (m_prefabBuilder != null) { node.Data.ScriptClassName = PrefabBuilderUtility.GUINameToClassName(selectedGUIName); node.Data.InstanceData.DefaultValue = m_prefabBuilder.Serialize(); } } } ); } } } } else { if (!string.IsNullOrEmpty(node.Data.ScriptClassName)) { EditorGUILayout.HelpBox( string.Format( "Your PrefabBuilder script {0} is missing from assembly. Did you delete script?", node.Data.ScriptClassName), MessageType.Info); } else { string[] menuNames = AssetBundleGraphSettings.GUI_TEXT_MENU_GENERATE_PREFABBUILDER.Split('/'); EditorGUILayout.HelpBox( string.Format( "You need to create at least one PrefabBuilder script to use PrefabBuilder node. To start, select {0}>{1}>{2} menu and create new script from template.", menuNames[1], menuNames[2], menuNames[3] ), MessageType.Info); } } GUILayout.Space(10f); if (DrawPlatformSelector(node)) { // if platform tab is changed, renew prefabBuilder for that tab. m_prefabBuilder = null; } using (new EditorGUILayout.VerticalScope()) { var disabledScope = DrawOverrideTargetToggle(node, node.Data.InstanceData.ContainsValueOf(currentEditingGroup), (bool enabled) => { if (enabled) { node.Data.InstanceData[currentEditingGroup] = node.Data.InstanceData.DefaultValue; } else { node.Data.InstanceData.Remove(currentEditingGroup); } m_prefabBuilder = null; }); using (disabledScope) { //reload prefabBuilder instance from saved instance data. if (m_prefabBuilder == null) { m_prefabBuilder = PrefabBuilderUtility.CreatePrefabBuilder(node.Data, currentEditingGroup); if (m_prefabBuilder != null) { node.Data.ScriptClassName = m_prefabBuilder.GetType().FullName; if (node.Data.InstanceData.ContainsValueOf(currentEditingGroup)) { node.Data.InstanceData[currentEditingGroup] = m_prefabBuilder.Serialize(); } } } if (m_prefabBuilder != null) { Action onChangedAction = () => { using (new RecordUndoScope("Change PrefabBuilder Setting", node)) { node.Data.ScriptClassName = m_prefabBuilder.GetType().FullName; if (node.Data.InstanceData.ContainsValueOf(currentEditingGroup)) { node.Data.InstanceData[currentEditingGroup] = m_prefabBuilder.Serialize(); } } }; m_prefabBuilder.OnInspectorGUI(onChangedAction); } } } } }
public void Run(BuildTarget target, NodeData node, IEnumerable <PerformGraph.AssetGroups> incoming, IEnumerable <ConnectionData> connectionsToOutput, PerformGraph.Output Output, Action <NodeData, string, float> progressFunc) { if (incoming == null) { return; } var builder = PrefabBuilderUtility.CreatePrefabBuilder(node, target); UnityEngine.Assertions.Assert.IsNotNull(builder); var prefabOutputDir = FileUtility.EnsurePrefabBuilderCacheDirExists(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()); } } foreach (var key in aggregatedGroups.Keys) { var assets = aggregatedGroups[key]; var allAssets = LoadAllAssets(assets); var prefabFileName = builder.CanCreatePrefab(key, allAssets); var prefabSavePath = FileUtility.PathCombine(prefabOutputDir, prefabFileName + ".prefab"); if (PrefabBuildInfo.DoesPrefabNeedRebuilding(node, target, key, assets)) { UnityEngine.GameObject obj = builder.CreatePrefab(key, allAssets); if (obj == null) { throw new AssetBundleGraphException(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(node.ScriptClassName), PrefabBuilderUtility.GetPrefabBuilderVersion(node.ScriptClassName)); if (progressFunc != null) { progressFunc(node, string.Format("Creating {0}", prefabFileName), 0.5f); } PrefabUtility.CreatePrefab(prefabSavePath, obj, node.ReplacePrefabOptions); PrefabBuildInfo.SavePrefabBuildInfo(node, target, key, assets); GameObject.DestroyImmediate(obj); } allAssets.ForEach(o => Resources.UnloadAsset(o)); if (output != null) { output[key] = new List <AssetReference> () { AssetReferenceDatabase.GetPrefabReference(prefabSavePath) }; } aggregatedGroups[key].ForEach(a => a.ReleaseData()); } if (Output != null) { var dst = (connectionsToOutput == null || !connectionsToOutput.Any())? null : connectionsToOutput.First(); Output(dst, output); } }