public static void ApplyActionLeafFirst(GraphData graph, Action<AbstractMaterialNode> action) { var temporaryMarks = PooledHashSet<Guid>.Get(); var permanentMarks = PooledHashSet<Guid>.Get(); var slots = ListPool<MaterialSlot>.Get(); // Make sure we process a node's children before the node itself. var stack = StackPool<AbstractMaterialNode>.Get(); foreach (var node in graph.GetNodes<AbstractMaterialNode>()) { stack.Push(node); } while (stack.Count > 0) { var node = stack.Pop(); if (permanentMarks.Contains(node.guid)) { continue; } if (temporaryMarks.Contains(node.guid)) { action.Invoke(node); permanentMarks.Add(node.guid); } else { temporaryMarks.Add(node.guid); stack.Push(node); node.GetInputSlots(slots); foreach (var inputSlot in slots) { var nodeEdges = graph.GetEdges(inputSlot.slotReference); foreach (var edge in nodeEdges) { var fromSocketRef = edge.outputSlot; var childNode = graph.GetNodeFromGuid(fromSocketRef.nodeGuid); if (childNode != null) { stack.Push(childNode); } } } slots.Clear(); } } StackPool<AbstractMaterialNode>.Release(stack); ListPool<MaterialSlot>.Release(slots); temporaryMarks.Dispose(); permanentMarks.Dispose(); }
public override void OnImportAsset(AssetImportContext ctx) { var graphAsset = ScriptableObject.CreateInstance <SubGraphAsset>(); var subGraphPath = ctx.assetPath; var subGraphGuid = AssetDatabase.AssetPathToGUID(subGraphPath); graphAsset.assetGuid = subGraphGuid; var textGraph = File.ReadAllText(subGraphPath, Encoding.UTF8); var graphData = new GraphData { isSubGraph = true, assetGuid = subGraphGuid }; var messageManager = new MessageManager(); graphData.messageManager = messageManager; JsonUtility.FromJsonOverwrite(textGraph, graphData); try { ProcessSubGraph(graphAsset, graphData); } catch (Exception e) { graphAsset.isValid = false; Debug.LogException(e, graphAsset); } finally { if (messageManager.nodeMessagesChanged) { graphAsset.isValid = false; foreach (var pair in messageManager.GetNodeMessages()) { var node = graphData.GetNodeFromGuid(pair.Key); foreach (var message in pair.Value) { MessageManager.Log(node, subGraphPath, message, graphAsset); } } } messageManager.ClearAll(); } Texture2D texture = Resources.Load <Texture2D>("Icons/sg_subgraph_icon@64"); ctx.AddObjectToAsset("MainAsset", graphAsset, texture); ctx.SetMainObject(graphAsset); }
public override void OnImportAsset(AssetImportContext ctx) { var oldShader = AssetDatabase.LoadAssetAtPath <Shader>(ctx.assetPath); if (oldShader != null) { ShaderUtil.ClearShaderMessages(oldShader); } List <PropertyCollector.TextureInfo> configuredTextures; string path = ctx.assetPath; var sourceAssetDependencyPaths = new List <string>(); UnityEngine.Object mainObject; var textGraph = File.ReadAllText(path, Encoding.UTF8); GraphData graph = JsonUtility.FromJson <GraphData>(textGraph); graph.messageManager = new MessageManager(); graph.assetGuid = AssetDatabase.AssetPathToGUID(path); graph.OnEnable(); graph.ValidateGraph(); if (graph.outputNode is VfxMasterNode vfxMasterNode) { var vfxAsset = GenerateVfxShaderGraphAsset(vfxMasterNode); mainObject = vfxAsset; } else { var text = GetShaderText(path, out configuredTextures, sourceAssetDependencyPaths, graph); var shader = ShaderUtil.CreateShaderAsset(text, false); if (graph != null && graph.messageManager.nodeMessagesChanged) { foreach (var pair in graph.messageManager.GetNodeMessages()) { var node = graph.GetNodeFromGuid(pair.Key); MessageManager.Log(node, path, pair.Value.First(), shader); } } EditorMaterialUtility.SetShaderDefaults( shader, configuredTextures.Where(x => x.modifiable).Select(x => x.name).ToArray(), configuredTextures.Where(x => x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray()); EditorMaterialUtility.SetShaderNonModifiableDefaults( shader, configuredTextures.Where(x => !x.modifiable).Select(x => x.name).ToArray(), configuredTextures.Where(x => !x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray()); mainObject = shader; } Texture2D texture = Resources.Load <Texture2D>("Icons/sg_graph_icon@64"); ctx.AddObjectToAsset("MainAsset", mainObject, texture); ctx.SetMainObject(mainObject); var metadata = ScriptableObject.CreateInstance <ShaderGraphMetadata>(); metadata.hideFlags = HideFlags.HideInHierarchy; if (graph != null) { metadata.outputNodeTypeName = graph.outputNode.GetType().FullName; } ctx.AddObjectToAsset("Metadata", metadata); foreach (var sourceAssetDependencyPath in sourceAssetDependencyPaths.Distinct()) { // Ensure that dependency path is relative to project if (!sourceAssetDependencyPath.StartsWith("Packages/") && !sourceAssetDependencyPath.StartsWith("Assets/")) { Debug.LogWarning($"Invalid dependency path: {sourceAssetDependencyPath}", mainObject); continue; } ctx.DependsOnSourceAsset(sourceAssetDependencyPath); } }