internal static void InsertCopyPasteGraph(this MaterialGraphView graphView, CopyPasteGraph copyGraph) { if (copyGraph == null) { return; } // Make new properties from the copied graph foreach (AbstractShaderProperty property in copyGraph.properties) { string propertyName = graphView.graph.SanitizePropertyName(property.displayName); AbstractShaderProperty copiedProperty = property.Copy(); copiedProperty.displayName = propertyName; graphView.graph.AddShaderProperty(copiedProperty); // Update the property nodes that depends on the copied node var dependentPropertyNodes = copyGraph.GetNodes <PropertyNode>().Where(x => x.propertyGuid == property.guid); foreach (var node in dependentPropertyNodes) { node.owner = graphView.graph; node.propertyGuid = copiedProperty.guid; } } using (var remappedNodesDisposable = ListPool <AbstractMaterialNode> .GetDisposable()) { using (var remappedEdgesDisposable = ListPool <IEdge> .GetDisposable()) { var remappedNodes = remappedNodesDisposable.value; var remappedEdges = remappedEdgesDisposable.value; graphView.graph.PasteGraph(copyGraph, remappedNodes, remappedEdges); if (graphView.graph.assetGuid != copyGraph.sourceGraphGuid) { // Compute the mean of the copied nodes. Vector2 centroid = Vector2.zero; var count = 1; foreach (var node in remappedNodes) { var position = node.drawState.position.position; centroid = centroid + (position - centroid) / count; ++count; } // Get the center of the current view var viewCenter = graphView.contentViewContainer.WorldToLocal(graphView.layout.center); foreach (var node in remappedNodes) { var drawState = node.drawState; var positionRect = drawState.position; var position = positionRect.position; position += viewCenter - centroid; positionRect.position = position; drawState.position = positionRect; node.drawState = drawState; } } // Add new elements to selection graphView.ClearSelection(); graphView.graphElements.ForEach(element => { if (element is Edge edge && remappedEdges.Contains(edge.userData as IEdge)) { graphView.AddToSelection(edge); } if (element is IShaderNodeView nodeView && remappedNodes.Contains(nodeView.node)) { graphView.AddToSelection((Node)nodeView); } }); } } }
void CreateNode(object obj, Vector2 nodePosition) { var texture2D = obj as Texture2D; if (texture2D != null) { graph.owner.RegisterCompleteObjectUndo("Drag Texture"); bool isNormalMap = false; if (EditorUtility.IsPersistent(texture2D) && !string.IsNullOrEmpty(AssetDatabase.GetAssetPath(texture2D))) { var importer = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(texture2D)) as TextureImporter; if (importer != null) { isNormalMap = importer.textureType == TextureImporterType.NormalMap; } } var node = new SampleTexture2DNode(); var drawState = node.drawState; drawState.position = new Rect(nodePosition, drawState.position.size); node.drawState = drawState; graph.AddNode(node); if (isNormalMap) { node.textureType = TextureType.Normal; } var inputslot = node.FindInputSlot <Texture2DInputMaterialSlot>(SampleTexture2DNode.TextureInputId); if (inputslot != null) { inputslot.texture = texture2D; } } var textureArray = obj as Texture2DArray; if (textureArray != null) { graph.owner.RegisterCompleteObjectUndo("Drag Texture Array"); var property = new Texture2DArrayShaderProperty { displayName = textureArray.name, value = { textureArray = textureArray } }; graph.AddShaderProperty(property); var node = new SampleTexture2DArrayNode(); var drawState = node.drawState; drawState.position = new Rect(nodePosition, drawState.position.size); node.drawState = drawState; graph.AddNode(node); var inputslot = node.FindSlot <Texture2DArrayInputMaterialSlot>(SampleTexture2DArrayNode.TextureInputId); if (inputslot != null) { inputslot.textureArray = textureArray; } } var texture3D = obj as Texture3D; if (texture3D != null) { graph.owner.RegisterCompleteObjectUndo("Drag Texture 3D"); var property = new Texture3DShaderProperty { displayName = texture3D.name, value = { texture = texture3D } }; graph.AddShaderProperty(property); var node = new SampleTexture3DNode(); var drawState = node.drawState; drawState.position = new Rect(nodePosition, drawState.position.size); node.drawState = drawState; graph.AddNode(node); var inputslot = node.FindSlot <Texture3DInputMaterialSlot>(SampleTexture3DNode.TextureInputId); if (inputslot != null) { inputslot.texture = texture3D; } } var cubemap = obj as Cubemap; if (cubemap != null) { graph.owner.RegisterCompleteObjectUndo("Drag Cubemap"); var property = new CubemapShaderProperty { displayName = cubemap.name, value = { cubemap = cubemap } }; graph.AddShaderProperty(property); var node = new SampleCubemapNode(); var drawState = node.drawState; drawState.position = new Rect(nodePosition, drawState.position.size); node.drawState = drawState; graph.AddNode(node); var inputslot = node.FindInputSlot <CubemapInputMaterialSlot>(SampleCubemapNode.CubemapInputId); if (inputslot != null) { inputslot.cubemap = cubemap; } } var subGraphAsset = obj as SubGraphAsset; if (subGraphAsset != null) { graph.owner.RegisterCompleteObjectUndo("Drag Sub-Graph"); var node = new SubGraphNode(); var drawState = node.drawState; drawState.position = new Rect(nodePosition, drawState.position.size); node.drawState = drawState; node.subGraphAsset = subGraphAsset; graph.AddNode(node); } var blackboardField = obj as BlackboardField; if (blackboardField != null) { AbstractShaderProperty property = blackboardField.userData as AbstractShaderProperty; if (property != null) { graph.owner.RegisterCompleteObjectUndo("Drag Property"); var node = new PropertyNode(); var drawState = node.drawState; drawState.position = new Rect(nodePosition, drawState.position.size); node.drawState = drawState; graph.AddNode(node); // Setting the guid requires the graph to be set first. node.propertyGuid = property.guid; } } }