浏览代码

Unify {Abstract,Serializable,Material}GraphEditWindow, {Abstract,Serializable,Material}GraphPresenter and {Serializable,Material}GraphView

/main
Peter Bay Bastian 7 年前
当前提交
d470f1f1
共有 17 个文件被更改,包括 604 次插入974 次删除
  1. 5
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/Drawer/GraphEditorDrawer.cs
  2. 3
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/Manipulators/ClickGlobalSelector.cs
  3. 15
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/Presenters/TitleBarPresenter.cs
  4. 12
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Drawer/MaterialNodeDrawer.cs
  5. 155
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/MaterialGraphEditWindow.cs
  6. 182
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/MaterialGraphView.cs
  7. 317
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Presenters/MaterialGraphPresenter.cs
  8. 12
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/GraphEditWindow.cs.meta
  9. 12
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/AbstractGraphEditWindow.cs.meta
  10. 12
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/SerializableGraphView.cs.meta
  11. 12
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/SerializedGraphPresenter.cs
  12. 12
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/AbstractGraphPresenter.cs.meta
  13. 12
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/SerializedGraphPresenter.cs.meta
  14. 328
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/AbstractGraphPresenter.cs
  15. 322
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/AbstractGraphEditWindow.cs
  16. 17
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/GraphEditWindow.cs
  17. 150
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/SerializableGraphView.cs

5
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/Drawer/GraphEditorDrawer.cs


using UnityEditor.Experimental.UIElements.GraphView;
using UnityEditor.MaterialGraph.Drawing;
using UnityEngine;
namespace UnityEditor.Graphing.Drawing

m_TitleBarDrawer.dataProvider = m_Presenter.titleBar;
}
private AbstractGraphPresenter m_Presenter;
private MaterialGraphPresenter m_Presenter;
public AbstractGraphPresenter presenter
public MaterialGraphPresenter presenter
{
get { return m_Presenter; }
set

3
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/Manipulators/ClickGlobalSelector.cs


using System;
using UnityEditor.Experimental.UIElements.GraphView;
using UnityEditor.MaterialGraph.Drawing;
using UnityEngine.Experimental.UIElements;
using ManipulatorActivationFilter = UnityEngine.Experimental.UIElements.ManipulatorActivationFilter;
using MouseButton = UnityEngine.Experimental.UIElements.MouseButton;

public void HandleEvent(MouseEventBase evt)
{
var graphView = target as SerializableGraphView;
var graphView = target as MaterialGraphView;
if (graphView == null)
throw new InvalidOperationException("Manipulator can only be added to a SerializableGraphView");

15
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/Presenters/TitleBarPresenter.cs


using UnityEngine.MaterialGraph;
using System.IO;
using System.Linq;
using UnityEditor.MaterialGraph.Drawing;
public class TitleBarPresenter : ScriptableObject
public class TitleBarPresenter : ScriptableObject
AbstractGraphEditWindow m_Owner;
MaterialGraphEditWindow m_Owner;
public IEnumerable<TitleBarButtonPresenter> leftItems
{

protected TitleBarPresenter()
{}
public void Initialize(AbstractGraphEditWindow graphWindow)
public void Initialize(MaterialGraphEditWindow graphWindow)
{
m_Owner = graphWindow;
m_leftItems = new List<TitleBarButtonPresenter>();

m_Owner.PingAsset ();
}
class CallbackData
{
public IGraphAsset asset;
public AbstractGraphEditWindow owner;
}
public static List<IGraphAsset> FindAssets()
{
var assets = new List<IGraphAsset>();

}
return assets;
}
void UpdateAsset()
{
m_Owner.UpdateAsset ();

12
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Drawer/MaterialNodeDrawer.cs


VisualContainer m_ControlsContainer;
List<GraphControlPresenter> m_CurrentControlPresenter;
Image m_PreviewImage;
NodePreviewPresenter m_currentPreviewData;
NodePreviewPresenter m_CurrentPreviewData;
bool m_IsScheduled;
public MaterialNodeDrawer()

if (childrenNodes.OfType<IRequiresTime>().Any())
{
data.OnModified(ModificationScope.Node);
UpdatePreviewTexture(m_currentPreviewData);
UpdatePreviewTexture(m_CurrentPreviewData);
}
ListPool<INode>.Release(childrenNodes);
}

m_ControlsContainer.Clear();
m_CurrentControlPresenter.Clear();
m_PreviewImage.AddToClassList("inactive");
m_currentPreviewData = null;
UpdatePreviewTexture(m_currentPreviewData);
m_CurrentPreviewData = null;
UpdatePreviewTexture(m_CurrentPreviewData);
m_currentPreviewData = nodeData.elements.OfType<NodePreviewPresenter>().FirstOrDefault();
UpdatePreviewTexture(m_currentPreviewData);
m_CurrentPreviewData = nodeData.elements.OfType<NodePreviewPresenter>().FirstOrDefault();
UpdatePreviewTexture(m_CurrentPreviewData);
if (nodeData.expanded)
m_PreviewImage.RemoveFromClassList("hidden");

155
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/MaterialGraphEditWindow.cs


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEditor.Experimental.UIElements.GraphView;
using UnityEditor.Graphing.Drawing;
using UnityEngine;

namespace UnityEditor.MaterialGraph.Drawing
{
public class MaterialGraphEditWindow : AbstractGraphEditWindow
public class MaterialGraphEditWindow : EditorWindow, ISerializationCallbackReceiver
public static bool allowAlwaysRepaint = true;
bool shouldRepaint
{
get { return allowAlwaysRepaint && inMemoryAsset != null && inMemoryAsset.shouldRepaint; }
}
private Object m_Selected;
Object m_Selected;
private MaterialGraphAsset m_InMemoryAsset;
MaterialGraphAsset m_InMemoryAsset;
GraphEditorDrawer m_GraphEditorDrawer;
public override IGraphAsset inMemoryAsset
public IGraphAsset inMemoryAsset
public override Object selected
public Object selected
public override AbstractGraphPresenter CreateDataSource()
public MaterialGraphPresenter CreateDataSource()
public override GraphView CreateGraphView()
public GraphView CreateGraphView()
void OnEnable()
{
m_GraphEditorDrawer = new GraphEditorDrawer(CreateGraphView());
rootVisualContainer.Add(m_GraphEditorDrawer);
var source = CreateDataSource();
source.Initialize(inMemoryAsset, this);
m_GraphEditorDrawer.presenter = source;
}
void OnDisable()
{
rootVisualContainer.Clear();
}
void Update()
{
if (shouldRepaint)
Repaint();
}
public void PingAsset()
{
if (selected != null)
EditorGUIUtility.PingObject(selected);
}
public void UpdateAsset()
{
if (selected != null && inMemoryAsset != null)
{
var path = AssetDatabase.GetAssetPath(selected);
if (string.IsNullOrEmpty(path) || inMemoryAsset == null)
{
return;
}
var masterNode = ((MaterialGraphAsset)inMemoryAsset).materialGraph.masterNode;
if (masterNode == null)
return;
List<PropertyGenerator.TextureInfo> configuredTextures;
masterNode.GetFullShader(GenerationMode.ForReals, "NotNeeded", out configuredTextures);
var shaderImporter = AssetImporter.GetAtPath(path) as ShaderImporter;
if (shaderImporter == null)
return;
var textureNames = new List<string>();
var textures = new List<Texture>();
foreach (var textureInfo in configuredTextures.Where(
x => x.modifiable == TexturePropertyChunk.ModifiableState.Modifiable))
{
var texture = EditorUtility.InstanceIDToObject(textureInfo.textureId) as Texture;
if (texture == null)
continue;
textureNames.Add(textureInfo.name);
textures.Add(texture);
}
shaderImporter.SetDefaultTextures(textureNames.ToArray(), textures.ToArray());
textureNames.Clear();
textures.Clear();
foreach (var textureInfo in configuredTextures.Where(
x => x.modifiable == TexturePropertyChunk.ModifiableState.NonModifiable))
{
var texture = EditorUtility.InstanceIDToObject(textureInfo.textureId) as Texture;
if (texture == null)
continue;
textureNames.Add(textureInfo.name);
textures.Add(texture);
}
shaderImporter.SetNonModifiableTextures(textureNames.ToArray(), textures.ToArray());
File.WriteAllText(path, EditorJsonUtility.ToJson(inMemoryAsset.graph));
shaderImporter.SaveAndReimport();
AssetDatabase.ImportAsset(path);
}
}
public virtual void ToggleRequiresTime()
{
allowAlwaysRepaint = !allowAlwaysRepaint;
}
public void ChangeSelction(Object newSelection)
{
if (!EditorUtility.IsPersistent(newSelection))
return;
if (selected == newSelection)
return;
if (selected != null)
{
if (EditorUtility.DisplayDialog("Save Old Graph?", "Save Old Graph?", "yes!", "no"))
{
UpdateAsset();
}
}
selected = newSelection;
var mGraph = CreateInstance<MaterialGraphAsset>();
var path = AssetDatabase.GetAssetPath(newSelection);
var textGraph = File.ReadAllText(path, Encoding.UTF8);
mGraph.materialGraph = JsonUtility.FromJson<UnityEngine.MaterialGraph.MaterialGraph>(textGraph);
inMemoryAsset = mGraph;
var graph = inMemoryAsset.graph;
graph.OnEnable();
graph.ValidateGraph();
var source = CreateDataSource();
source.Initialize(inMemoryAsset, this);
m_GraphEditorDrawer.presenter = source;
//m_GraphView.StretchToParentSize();
Repaint();
/*if (refocus)
{
focused = false;
m_GraphEditorDrawer.graphView.Schedule (Focus).StartingIn (1).Until (() => focused);
}*/
}
public void OnBeforeSerialize() { }
public void OnAfterDeserialize() { }
}
}

182
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/MaterialGraphView.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditor.Experimental.UIElements.GraphView;
using UnityEditor.Graphing.Drawing;

namespace UnityEditor.MaterialGraph.Drawing
{
public class MaterialGraphView : SerializableGraphView
public sealed class MaterialGraphView : GraphView
public MaterialGraphView(EditorWindow editorWindow) : base(editorWindow)
public MaterialGraphView(EditorWindow editorWindow)
var shortcutHandler = new ShortcutHandler(
new Dictionary<Event, ShortcutDelegate>
{
{Event.KeyboardEvent("a"), FrameAll},
{Event.KeyboardEvent("f"), FrameSelection},
{Event.KeyboardEvent("o"), FrameOrigin},
{Event.KeyboardEvent("delete"), DeleteSelection},
{Event.KeyboardEvent("#tab"), FramePrev},
{Event.KeyboardEvent("tab"), FrameNext},
{Event.KeyboardEvent("#c"), CopySelection},
{Event.KeyboardEvent("#v"), Paste},
{Event.KeyboardEvent("#d"), DuplicateSelection}
});
onEnter += () => editorWindow.rootVisualContainer.parent.AddManipulator(shortcutHandler);
onLeave += () => editorWindow.rootVisualContainer.parent.RemoveManipulator(shortcutHandler);
this.AddManipulator(new Commandable
{
{ "Duplicate", () => true, () => Debug.Log("Duplicate!") },
{ "Copy", () => true, () => Debug.Log("Copy!") }
});
this.AddManipulator(new ClickGlobalSelector());
this.AddManipulator(new ContentZoomer());
this.AddManipulator(new ContentDragger());
this.AddManipulator(new RectangleSelector());
this.AddManipulator(new SelectionDragger());
this.AddManipulator(new ClickSelector());
Insert(0, new GridBackground());
typeFactory[typeof(GraphNodePresenter)] = typeof(NodeDrawer);
RegisterCallback<MouseUpEvent>(DoContextMenu);
typeFactory[typeof(MaterialNodePresenter)] = typeof(MaterialNodeDrawer);

AddStyleSheetPath("Styles/MaterialGraph");
}
public virtual bool CanAddToNodeMenu(Type type)
public bool CanAddToNodeMenu(Type type)
protected void DoContextMenu(MouseUpEvent evt)
void DoContextMenu(MouseUpEvent evt)
{
if (evt.button == (int)MouseButton.RightMouse)
{

evt.StopPropagation();
}
private class AddNodeCreationObject
class AddNodeCreationObject
{
public Vector2 m_Pos;
public readonly Type m_Type;

}
};
private void AddNode(object obj)
void AddNode(object obj)
{
var posObj = obj as AddNodeCreationObject;
if (posObj == null)

drawstate.position = new Rect(localPos.x, localPos.y, 0, 0);
node.drawState = drawstate;
var graphDataSource = GetPresenter<AbstractGraphPresenter>();
var graphDataSource = GetPresenter<MaterialGraphPresenter>();
/*
public EventPropagation Export()
// TODO JOCE Remove the "new" here. Use the base class' impl
new EventPropagation DeleteSelection()
var path = EditorUtility.SaveFilePanelInProject("Export shader to file...", "shader.shader", "shader", "Enter file name");
var nodalViewData = GetPresenter<MaterialGraphPresenter>();
if (nodalViewData == null)
return EventPropagation.Stop;
var ds = presenter as AbstractGraphPresenter;
if (ds != null && !string.IsNullOrEmpty(path))
{
ExportShader(ds.graphAsset as MaterialGraphAsset, path);
}
else
EditorUtility.DisplayDialog("Export Shader Error", "Cannot export shader", "Ok");
nodalViewData.RemoveElements(
selection.OfType<MaterialNodeDrawer>().Select(x => x.GetPresenter<GraphNodePresenter>()),
selection.OfType<Edge>().Select(x => x.GetPresenter<GraphEdgePresenter>())
);
public static Shader ExportShader(MaterialGraphAsset graphAsset, string path)
public override void OnDataChanged()
if (graphAsset == null)
return null;
base.OnDataChanged();
var materialGraph = graphAsset.graph as UnityEngine.MaterialGraph.MaterialGraph;
if (materialGraph == null)
return null;
var graphDataSource = GetPresenter<MaterialGraphPresenter>();
if (graphDataSource == null)
return;
List<PropertyGenerator.TextureInfo> configuredTextures;
var shaderString = materialGraph.masterNode.GetShader(GenerationMode.ForReals, out configuredTextures);
File.WriteAllText(path, shaderString);
AssetDatabase.Refresh(); // Investigate if this is optimal
var graphAsset = graphDataSource.graphAsset;
if (graphAsset == null || graphAsset.drawingData.selection.SequenceEqual(selection.OfType<NodeDrawer>().Select(d => ((GraphNodePresenter) d.presenter).node.guid))) return;
var shader = AssetDatabase.LoadAssetAtPath(path, typeof(Shader)) as Shader;
if (shader == null)
return null;
var selectedDrawers = graphDataSource.graphAsset.drawingData.selection
.Select(guid => contentViewContainer
.OfType<NodeDrawer>()
.FirstOrDefault(drawer => ((GraphNodePresenter) drawer.presenter).node.guid == guid))
.ToList();
var shaderImporter = AssetImporter.GetAtPath(path) as ShaderImporter;
if (shaderImporter == null)
return null;
ClearSelection();
foreach (var drawer in selectedDrawers)
AddToSelection(drawer);
}
public void SetGlobalSelection()
{
var graphDataSource = GetPresenter<MaterialGraphPresenter>();
if (graphDataSource == null || graphDataSource.graphAsset == null)
return;
//Selection.activeObject = graphDataSource.graphAsset.GetScriptableObject();
}
var textureNames = new List<string>();
var textures = new List<Texture>();
foreach (var textureInfo in configuredTextures.Where(x => x.modifiable == TexturePropertyChunk.ModifiableState.Modifiable))
{
var texture = EditorUtility.InstanceIDToObject(textureInfo.textureId) as Texture;
if (texture == null)
continue;
textureNames.Add(textureInfo.name);
textures.Add(texture);
}
shaderImporter.SetDefaultTextures(textureNames.ToArray(), textures.ToArray());
void PropagateSelection()
{
var graphDataSource = GetPresenter<MaterialGraphPresenter>();
if (graphDataSource == null || graphDataSource.graphAsset == null)
return;
var selectedNodeGuids = selection.OfType<NodeDrawer>().Select(x => ((GraphNodePresenter) x.presenter).node.guid);
graphDataSource.graphAsset.drawingData.selection = selectedNodeGuids;
}
public override void AddToSelection(ISelectable selectable)
{
base.AddToSelection(selectable);
PropagateSelection();
}
public override void RemoveFromSelection(ISelectable selectable)
{
base.RemoveFromSelection(selectable);
PropagateSelection();
}
public override void ClearSelection()
{
base.ClearSelection();
PropagateSelection();
}
textureNames.Clear();
textures.Clear();
foreach (var textureInfo in configuredTextures.Where(x => x.modifiable == TexturePropertyChunk.ModifiableState.NonModifiable))
{
var texture = EditorUtility.InstanceIDToObject(textureInfo.textureId) as Texture;
if (texture == null)
continue;
textureNames.Add(textureInfo.name);
textures.Add(texture);
}
shaderImporter.SetNonModifiableTextures(textureNames.ToArray(), textures.ToArray());
public EventPropagation CopySelection()
{
var graphDataSource = GetPresenter<MaterialGraphPresenter>();
if (selection.Any() && graphDataSource != null)
graphDataSource.Copy(selection.OfType<GraphElement>().Select(ge => ge.presenter));
return EventPropagation.Stop;
}
shaderImporter.SaveAndReimport();
public EventPropagation DuplicateSelection()
{
var graphDataSource = GetPresenter<MaterialGraphPresenter>();
if (selection.Any() && graphDataSource != null)
graphDataSource.Duplicate(selection.OfType<GraphElement>().Select(ge => ge.presenter));
return EventPropagation.Stop;
}
return shaderImporter.GetShader();
}*/
public EventPropagation Paste()
{
var graphDataSource = GetPresenter<MaterialGraphPresenter>();
if (graphDataSource != null)
graphDataSource.Paste();
return EventPropagation.Stop;
}
}
}

317
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Presenters/MaterialGraphPresenter.cs


using System;
using UnityEditor.Graphing.Util;
using UnityEngine;
using UnityEngine.Graphing;
public class MaterialGraphPresenter : AbstractGraphPresenter
[Serializable]
public class MaterialGraphPresenter : GraphViewPresenter
protected GraphTypeMapper typeMapper { get; set; }
public IGraphAsset graphAsset { get; private set; }
[SerializeField]
private TitleBarPresenter m_TitleBar;
[SerializeField]
private EditorWindow m_Container;
public TitleBarPresenter titleBar
{
get { return m_TitleBar; }
}
typeMapper = new GraphTypeMapper(typeof(GraphNodePresenter));
typeMapper[typeof(AbstractMaterialNode)] = typeof(MaterialNodePresenter);
typeMapper[typeof(ColorNode)] = typeof(ColorNodePresenter);
typeMapper[typeof(GradientNode)] = typeof(GradientNodePresenter);

(startAnchor is GraphAnchorPresenter && ((GraphAnchorPresenter)nap).slot is MaterialSlot &&
((MaterialSlot)((GraphAnchorPresenter)startAnchor).slot).IsCompatibleWithInputSlotType(((MaterialSlot)((GraphAnchorPresenter)nap).slot).valueType)))
.ToList();
}
void OnNodeChanged(INode inNode, ModificationScope scope)
{
var dependentNodes = new List<INode>();
NodeUtils.CollectNodesNodeFeedsInto(dependentNodes, inNode);
foreach (var node in dependentNodes)
{
var theElements = m_Elements.OfType<GraphNodePresenter>().ToList();
var found = theElements.Where(x => x.node.guid == node.guid).ToList();
foreach (var drawableNodeData in found)
drawableNodeData.OnModified(scope);
}
if (scope == ModificationScope.Topological)
UpdateData();
EditorUtility.SetDirty(graphAsset.GetScriptableObject());
if (m_Container != null)
m_Container.Repaint();
}
private void UpdateData()
{
// Find all nodes currently being drawn which are no longer in the graph (i.e. deleted)
var deletedElements = m_Elements
.OfType<GraphNodePresenter>()
.Where(nd => !graphAsset.graph.GetNodes<INode>().Contains(nd.node))
.OfType<GraphElementPresenter>()
.ToList();
var deletedEdges = m_Elements.OfType<GraphEdgePresenter>()
.Where(ed => !graphAsset.graph.edges.Contains(ed.edge));
// Find all edges currently being drawn which are no longer in the graph (i.e. deleted)
foreach (var edgeData in deletedEdges)
{
// Make sure to disconnect the node, otherwise new connections won't be allowed for the used slots
edgeData.output.Disconnect(edgeData);
edgeData.input.Disconnect(edgeData);
var toNodeGuid = edgeData.edge.inputSlot.nodeGuid;
var toNode = m_Elements.OfType<GraphNodePresenter>().FirstOrDefault(nd => nd.node.guid == toNodeGuid);
if (toNode != null)
{
// Make the input node (i.e. right side of the connection) re-render
OnNodeChanged(toNode.node, ModificationScope.Graph);
}
deletedElements.Add(edgeData);
}
// Remove all nodes and edges marked for deletion
foreach (var deletedElement in deletedElements)
{
m_Elements.Remove(deletedElement);
}
var addedNodes = new List<GraphNodePresenter>();
// Find all new nodes and mark for addition
foreach (var node in graphAsset.graph.GetNodes<INode>())
{
// Check whether node already exists
if (m_Elements.OfType<GraphNodePresenter>().Any(e => e.node == node))
continue;
var nodeData = (GraphNodePresenter)typeMapper.Create(node);
node.onModified += OnNodeChanged;
nodeData.Initialize(node);
addedNodes.Add(nodeData);
}
// Create edge data for nodes marked for addition
var drawableEdges = new List<GraphEdgePresenter>();
foreach (var addedNode in addedNodes)
{
var baseNode = addedNode.node;
foreach (var slot in baseNode.GetOutputSlots<ISlot>())
{
var sourceAnchors = addedNode.elements.OfType<GraphAnchorPresenter>();
var sourceAnchor = sourceAnchors.FirstOrDefault(x => x.slot == slot);
var edges = baseNode.owner.GetEdges(new SlotReference(baseNode.guid, slot.id));
foreach (var edge in edges)
{
var toNode = baseNode.owner.GetNodeFromGuid(edge.inputSlot.nodeGuid);
var toSlot = toNode.FindInputSlot<ISlot>(edge.inputSlot.slotId);
var targetNode = addedNodes.FirstOrDefault(x => x.node == toNode);
var targetAnchors = targetNode.elements.OfType<GraphAnchorPresenter>();
var targetAnchor = targetAnchors.FirstOrDefault(x => x.slot == toSlot);
var edgeData = CreateInstance<GraphEdgePresenter>();
edgeData.Initialize(edge);
edgeData.output = sourceAnchor;
edgeData.output.Connect(edgeData);
edgeData.input = targetAnchor;
edgeData.input.Connect(edgeData);
drawableEdges.Add(edgeData);
}
}
}
// Add nodes marked for addition
m_Elements.AddRange(addedNodes.OfType<GraphElementPresenter>());
// Find edges in the graph that are not being drawn and create edge data for them
foreach (var edge in graphAsset.graph.edges)
{
if (!m_Elements.OfType<GraphEdgePresenter>().Any(ed => ed.edge == edge))
{
var fromNode = graphAsset.graph.GetNodeFromGuid(edge.outputSlot.nodeGuid);
var fromSlot = fromNode.FindOutputSlot<ISlot>(edge.outputSlot.slotId);
var sourceNode = m_Elements.OfType<GraphNodePresenter>().FirstOrDefault(x => x.node == fromNode);
var sourceAnchors = sourceNode.elements.OfType<GraphAnchorPresenter>();
var sourceAnchor = sourceAnchors.FirstOrDefault(x => x.slot == fromSlot);
var toNode = graphAsset.graph.GetNodeFromGuid(edge.inputSlot.nodeGuid);
var toSlot = toNode.FindInputSlot<ISlot>(edge.inputSlot.slotId);
var targetNode = m_Elements.OfType<GraphNodePresenter>().FirstOrDefault(x => x.node == toNode);
var targetAnchors = targetNode.elements.OfType<GraphAnchorPresenter>();
var targetAnchor = targetAnchors.FirstOrDefault(x => x.slot == toSlot);
OnNodeChanged(targetNode.node, ModificationScope.Graph);
var edgeData = CreateInstance<GraphEdgePresenter>();
edgeData.Initialize(edge);
edgeData.output = sourceAnchor;
edgeData.output.Connect(edgeData);
edgeData.input = targetAnchor;
edgeData.input.Connect(edgeData);
drawableEdges.Add(edgeData);
}
}
m_Elements.AddRange(drawableEdges.OfType<GraphElementPresenter>());
}
public virtual void Initialize(IGraphAsset graphAsset, MaterialGraphEditWindow container)
{
this.graphAsset = graphAsset;
m_Container = container;
m_TitleBar = CreateInstance<TitleBarPresenter>();
m_TitleBar.Initialize(container);
if (graphAsset == null)
return;
UpdateData();
}
public void AddNode(INode node)
{
graphAsset.graph.AddNode(node);
EditorUtility.SetDirty(graphAsset.GetScriptableObject());
UpdateData();
}
public void RemoveElements(IEnumerable<GraphNodePresenter> nodes, IEnumerable<GraphEdgePresenter> edges)
{
graphAsset.graph.RemoveElements(nodes.Select(x => x.node), edges.Select(x => x.edge));
graphAsset.graph.ValidateGraph();
EditorUtility.SetDirty(graphAsset.GetScriptableObject());
UpdateData();
}
public void Connect(GraphAnchorPresenter left, GraphAnchorPresenter right)
{
if (left != null && right != null)
{
graphAsset.graph.Connect(left.slot.slotReference, right.slot.slotReference);
EditorUtility.SetDirty(graphAsset.GetScriptableObject());
UpdateData();
}
}
private CopyPasteGraph CreateCopyPasteGraph(IEnumerable<GraphElementPresenter> selection)
{
var graph = new CopyPasteGraph();
foreach (var presenter in selection)
{
var nodePresenter = presenter as GraphNodePresenter;
if (nodePresenter != null)
{
graph.AddNode(nodePresenter.node);
foreach (var edge in NodeUtils.GetAllEdges(nodePresenter.node))
graph.AddEdge(edge);
}
var edgePresenter = presenter as GraphEdgePresenter;
if (edgePresenter != null)
graph.AddEdge(edgePresenter.edge);
}
return graph;
}
private CopyPasteGraph DeserializeCopyBuffer(string copyBuffer)
{
try
{
return JsonUtility.FromJson<CopyPasteGraph>(copyBuffer);
}
catch
{
// ignored. just means copy buffer was not a graph :(
return null;
}
}
private void InsertCopyPasteGraph(CopyPasteGraph graph)
{
if (graph == null || graphAsset == null || graphAsset.graph == null)
return;
var addedNodes = new List<INode>();
var nodeGuidMap = new Dictionary<Guid, Guid>();
foreach (var node in graph.GetNodes<INode>())
{
var oldGuid = node.guid;
var newGuid = node.RewriteGuid();
nodeGuidMap[oldGuid] = newGuid;
var drawState = node.drawState;
var position = drawState.position;
position.x += 30;
position.y += 30;
drawState.position = position;
node.drawState = drawState;
graphAsset.graph.AddNode(node);
addedNodes.Add(node);
}
// only connect edges within pasted elements, discard
// external edges.
var addedEdges = new List<IEdge>();
foreach (var edge in graph.edges)
{
var outputSlot = edge.outputSlot;
var inputSlot = edge.inputSlot;
Guid remappedOutputNodeGuid;
Guid remappedInputNodeGuid;
if (nodeGuidMap.TryGetValue(outputSlot.nodeGuid, out remappedOutputNodeGuid)
&& nodeGuidMap.TryGetValue(inputSlot.nodeGuid, out remappedInputNodeGuid))
{
var outputSlotRef = new SlotReference(remappedOutputNodeGuid, outputSlot.slotId);
var inputSlotRef = new SlotReference(remappedInputNodeGuid, inputSlot.slotId);
addedEdges.Add(graphAsset.graph.Connect(outputSlotRef, inputSlotRef));
}
}
graphAsset.graph.ValidateGraph();
UpdateData();
graphAsset.drawingData.selection = addedNodes.Select(n => n.guid);
}
public void Copy(IEnumerable<GraphElementPresenter> selection)
{
var graph = CreateCopyPasteGraph(selection);
EditorGUIUtility.systemCopyBuffer = JsonUtility.ToJson(graph, true);
}
public void Duplicate(IEnumerable<GraphElementPresenter> selection)
{
var graph = DeserializeCopyBuffer(JsonUtility.ToJson(CreateCopyPasteGraph(selection), true));
InsertCopyPasteGraph(graph);
}
public void Paste()
{
var pastedGraph = DeserializeCopyBuffer(EditorGUIUtility.systemCopyBuffer);
InsertCopyPasteGraph(pastedGraph);
}
public override void AddElement(EdgePresenter edge)
{
Connect(edge.output as GraphAnchorPresenter, edge.input as GraphAnchorPresenter);
}
public override void AddElement(GraphElementPresenter element)
{
throw new ArgumentException("Not supported on Serializable Graph, data comes from data store");
}
public override void RemoveElement(GraphElementPresenter element)
{
throw new ArgumentException("Not supported on Serializable Graph, data comes from data store");
}
}
}

12
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/GraphEditWindow.cs.meta


fileFormatVersion: 2
guid: 6f78144783978984fbcfe74ef28bd314
timeCreated: 1445419780
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

12
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/AbstractGraphEditWindow.cs.meta


fileFormatVersion: 2
guid: 322c21863b8e2024e85c4f0e0dee0b94
timeCreated: 1476711073
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

12
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/SerializableGraphView.cs.meta


fileFormatVersion: 2
guid: 0f06001291d4e32479f71557abf52944
timeCreated: 1476710182
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

12
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/SerializedGraphPresenter.cs


using UnityEngine.Graphing;
namespace UnityEditor.Graphing.Drawing
{
public class SerializedGraphPresenter : AbstractGraphPresenter
{
protected SerializedGraphPresenter()
{
typeMapper[typeof(SerializableNode)] = typeof(GraphNodePresenter);
}
}
}

12
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/AbstractGraphPresenter.cs.meta


fileFormatVersion: 2
guid: 194f855484623804c819a9132a24268f
timeCreated: 1476707366
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

12
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/SerializedGraphPresenter.cs.meta


fileFormatVersion: 2
guid: d7466f2e9546aaa409ea2125e36a0342
timeCreated: 1476711073
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

328
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/AbstractGraphPresenter.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor.Experimental.UIElements.GraphView;
using UnityEditor.Graphing.Util;
using UnityEngine;
using UnityEngine.Graphing;
namespace UnityEditor.Graphing.Drawing
{
[Serializable]
public abstract class AbstractGraphPresenter : GraphViewPresenter
{
protected GraphTypeMapper typeMapper { get; set; }
public IGraphAsset graphAsset { get; private set; }
[SerializeField]
private TitleBarPresenter m_TitleBar;
[SerializeField]
private EditorWindow m_Container;
public TitleBarPresenter titleBar
{
get { return m_TitleBar; }
}
protected AbstractGraphPresenter()
{
typeMapper = new GraphTypeMapper(typeof(GraphNodePresenter));
}
void OnNodeChanged(INode inNode, ModificationScope scope)
{
var dependentNodes = new List<INode>();
NodeUtils.CollectNodesNodeFeedsInto(dependentNodes, inNode);
foreach (var node in dependentNodes)
{
var theElements = m_Elements.OfType<GraphNodePresenter>().ToList();
var found = theElements.Where(x => x.node.guid == node.guid).ToList();
foreach (var drawableNodeData in found)
drawableNodeData.OnModified(scope);
}
if (scope == ModificationScope.Topological)
UpdateData();
EditorUtility.SetDirty(graphAsset.GetScriptableObject());
if (m_Container != null)
m_Container.Repaint();
}
private void UpdateData()
{
// Find all nodes currently being drawn which are no longer in the graph (i.e. deleted)
var deletedElements = m_Elements
.OfType<GraphNodePresenter>()
.Where(nd => !graphAsset.graph.GetNodes<INode>().Contains(nd.node))
.OfType<GraphElementPresenter>()
.ToList();
var deletedEdges = m_Elements.OfType<GraphEdgePresenter>()
.Where(ed => !graphAsset.graph.edges.Contains(ed.edge));
// Find all edges currently being drawn which are no longer in the graph (i.e. deleted)
foreach (var edgeData in deletedEdges)
{
// Make sure to disconnect the node, otherwise new connections won't be allowed for the used slots
edgeData.output.Disconnect(edgeData);
edgeData.input.Disconnect(edgeData);
var toNodeGuid = edgeData.edge.inputSlot.nodeGuid;
var toNode = m_Elements.OfType<GraphNodePresenter>().FirstOrDefault(nd => nd.node.guid == toNodeGuid);
if (toNode != null)
{
// Make the input node (i.e. right side of the connection) re-render
OnNodeChanged(toNode.node, ModificationScope.Graph);
}
deletedElements.Add(edgeData);
}
// Remove all nodes and edges marked for deletion
foreach (var deletedElement in deletedElements)
{
m_Elements.Remove(deletedElement);
}
var addedNodes = new List<GraphNodePresenter>();
// Find all new nodes and mark for addition
foreach (var node in graphAsset.graph.GetNodes<INode>())
{
// Check whether node already exists
if (m_Elements.OfType<GraphNodePresenter>().Any(e => e.node == node))
continue;
var nodeData = (GraphNodePresenter)typeMapper.Create(node);
node.onModified += OnNodeChanged;
nodeData.Initialize(node);
addedNodes.Add(nodeData);
}
// Create edge data for nodes marked for addition
var drawableEdges = new List<GraphEdgePresenter>();
foreach (var addedNode in addedNodes)
{
var baseNode = addedNode.node;
foreach (var slot in baseNode.GetOutputSlots<ISlot>())
{
var sourceAnchors = addedNode.elements.OfType<GraphAnchorPresenter>();
var sourceAnchor = sourceAnchors.FirstOrDefault(x => x.slot == slot);
var edges = baseNode.owner.GetEdges(new SlotReference(baseNode.guid, slot.id));
foreach (var edge in edges)
{
var toNode = baseNode.owner.GetNodeFromGuid(edge.inputSlot.nodeGuid);
var toSlot = toNode.FindInputSlot<ISlot>(edge.inputSlot.slotId);
var targetNode = addedNodes.FirstOrDefault(x => x.node == toNode);
var targetAnchors = targetNode.elements.OfType<GraphAnchorPresenter>();
var targetAnchor = targetAnchors.FirstOrDefault(x => x.slot == toSlot);
var edgeData = CreateInstance<GraphEdgePresenter>();
edgeData.Initialize(edge);
edgeData.output = sourceAnchor;
edgeData.output.Connect(edgeData);
edgeData.input = targetAnchor;
edgeData.input.Connect(edgeData);
drawableEdges.Add(edgeData);
}
}
}
// Add nodes marked for addition
m_Elements.AddRange(addedNodes.OfType<GraphElementPresenter>());
// Find edges in the graph that are not being drawn and create edge data for them
foreach (var edge in graphAsset.graph.edges)
{
if (!m_Elements.OfType<GraphEdgePresenter>().Any(ed => ed.edge == edge))
{
var fromNode = graphAsset.graph.GetNodeFromGuid(edge.outputSlot.nodeGuid);
var fromSlot = fromNode.FindOutputSlot<ISlot>(edge.outputSlot.slotId);
var sourceNode = m_Elements.OfType<GraphNodePresenter>().FirstOrDefault(x => x.node == fromNode);
var sourceAnchors = sourceNode.elements.OfType<GraphAnchorPresenter>();
var sourceAnchor = sourceAnchors.FirstOrDefault(x => x.slot == fromSlot);
var toNode = graphAsset.graph.GetNodeFromGuid(edge.inputSlot.nodeGuid);
var toSlot = toNode.FindInputSlot<ISlot>(edge.inputSlot.slotId);
var targetNode = m_Elements.OfType<GraphNodePresenter>().FirstOrDefault(x => x.node == toNode);
var targetAnchors = targetNode.elements.OfType<GraphAnchorPresenter>();
var targetAnchor = targetAnchors.FirstOrDefault(x => x.slot == toSlot);
OnNodeChanged(targetNode.node, ModificationScope.Graph);
var edgeData = CreateInstance<GraphEdgePresenter>();
edgeData.Initialize(edge);
edgeData.output = sourceAnchor;
edgeData.output.Connect(edgeData);
edgeData.input = targetAnchor;
edgeData.input.Connect(edgeData);
drawableEdges.Add(edgeData);
}
}
m_Elements.AddRange(drawableEdges.OfType<GraphElementPresenter>());
}
public virtual void Initialize(IGraphAsset graphAsset, AbstractGraphEditWindow container)
{
this.graphAsset = graphAsset;
m_Container = container;
m_TitleBar = CreateInstance<TitleBarPresenter>();
m_TitleBar.Initialize(container);
if (graphAsset == null)
return;
UpdateData();
}
public void AddNode(INode node)
{
graphAsset.graph.AddNode(node);
EditorUtility.SetDirty(graphAsset.GetScriptableObject());
UpdateData();
}
public void RemoveElements(IEnumerable<GraphNodePresenter> nodes, IEnumerable<GraphEdgePresenter> edges)
{
graphAsset.graph.RemoveElements(nodes.Select(x => x.node), edges.Select(x => x.edge));
graphAsset.graph.ValidateGraph();
EditorUtility.SetDirty(graphAsset.GetScriptableObject());
UpdateData();
}
public void Connect(GraphAnchorPresenter left, GraphAnchorPresenter right)
{
if (left != null && right != null)
{
graphAsset.graph.Connect(left.slot.slotReference, right.slot.slotReference);
EditorUtility.SetDirty(graphAsset.GetScriptableObject());
UpdateData();
}
}
private CopyPasteGraph CreateCopyPasteGraph(IEnumerable<GraphElementPresenter> selection)
{
var graph = new CopyPasteGraph();
foreach (var presenter in selection)
{
var nodePresenter = presenter as GraphNodePresenter;
if (nodePresenter != null)
{
graph.AddNode(nodePresenter.node);
foreach (var edge in NodeUtils.GetAllEdges(nodePresenter.node))
graph.AddEdge(edge);
}
var edgePresenter = presenter as GraphEdgePresenter;
if (edgePresenter != null)
graph.AddEdge(edgePresenter.edge);
}
return graph;
}
private CopyPasteGraph DeserializeCopyBuffer(string copyBuffer)
{
try
{
return JsonUtility.FromJson<CopyPasteGraph>(copyBuffer);
}
catch
{
// ignored. just means copy buffer was not a graph :(
return null;
}
}
private void InsertCopyPasteGraph(CopyPasteGraph graph)
{
if (graph == null || graphAsset == null || graphAsset.graph == null)
return;
var addedNodes = new List<INode>();
var nodeGuidMap = new Dictionary<Guid, Guid>();
foreach (var node in graph.GetNodes<INode>())
{
var oldGuid = node.guid;
var newGuid = node.RewriteGuid();
nodeGuidMap[oldGuid] = newGuid;
var drawState = node.drawState;
var position = drawState.position;
position.x += 30;
position.y += 30;
drawState.position = position;
node.drawState = drawState;
graphAsset.graph.AddNode(node);
addedNodes.Add(node);
}
// only connect edges within pasted elements, discard
// external edges.
var addedEdges = new List<IEdge>();
foreach (var edge in graph.edges)
{
var outputSlot = edge.outputSlot;
var inputSlot = edge.inputSlot;
Guid remappedOutputNodeGuid;
Guid remappedInputNodeGuid;
if (nodeGuidMap.TryGetValue(outputSlot.nodeGuid, out remappedOutputNodeGuid)
&& nodeGuidMap.TryGetValue(inputSlot.nodeGuid, out remappedInputNodeGuid))
{
var outputSlotRef = new SlotReference(remappedOutputNodeGuid, outputSlot.slotId);
var inputSlotRef = new SlotReference(remappedInputNodeGuid, inputSlot.slotId);
addedEdges.Add(graphAsset.graph.Connect(outputSlotRef, inputSlotRef));
}
}
graphAsset.graph.ValidateGraph();
UpdateData();
graphAsset.drawingData.selection = addedNodes.Select(n => n.guid);
}
public void Copy(IEnumerable<GraphElementPresenter> selection)
{
var graph = CreateCopyPasteGraph(selection);
EditorGUIUtility.systemCopyBuffer = JsonUtility.ToJson(graph, true);
}
public void Duplicate(IEnumerable<GraphElementPresenter> selection)
{
var graph = DeserializeCopyBuffer(JsonUtility.ToJson(CreateCopyPasteGraph(selection), true));
InsertCopyPasteGraph(graph);
}
public void Paste()
{
var pastedGraph = DeserializeCopyBuffer(EditorGUIUtility.systemCopyBuffer);
InsertCopyPasteGraph(pastedGraph);
}
public override void AddElement(EdgePresenter edge)
{
Connect(edge.output as GraphAnchorPresenter, edge.input as GraphAnchorPresenter);
}
public override void AddElement(GraphElementPresenter element)
{
throw new ArgumentException("Not supported on Serializable Graph, data comes from data store");
}
public override void RemoveElement(GraphElementPresenter element)
{
throw new ArgumentException("Not supported on Serializable Graph, data comes from data store");
}
}
}

322
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/AbstractGraphEditWindow.cs


using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEditor.Experimental.UIElements.GraphView;
using UnityEngine;
using UnityEngine.Graphing;
using UnityEngine.MaterialGraph;
using Object = UnityEngine.Object;
namespace UnityEditor.Graphing.Drawing
{
public abstract class AbstractGraphEditWindow : EditorWindow, ISerializationCallbackReceiver
{
public abstract IGraphAsset inMemoryAsset { get; set; }
public abstract Object selected { get; set; }
public static bool allowAlwaysRepaint = true;
private bool shouldRepaint
{
get
{
return allowAlwaysRepaint && inMemoryAsset != null && inMemoryAsset.shouldRepaint;
}
}
protected GraphView graphView
{
get { return m_GraphEditorDrawer.graphView; }
}
private GraphEditorDrawer m_GraphEditorDrawer;
public virtual AbstractGraphPresenter CreateDataSource()
{
return CreateInstance<SerializedGraphPresenter>();
}
public virtual GraphView CreateGraphView()
{
return new SerializableGraphView(this);
}
void OnEnable()
{
m_GraphEditorDrawer = new GraphEditorDrawer(CreateGraphView());
rootVisualContainer.Add(m_GraphEditorDrawer);
var source = CreateDataSource();
source.Initialize(inMemoryAsset, this);
m_GraphEditorDrawer.presenter = source;
}
void OnDisable()
{
rootVisualContainer.Clear();
}
void Update()
{
if (shouldRepaint)
Repaint();
}
public void PingAsset()
{
if (selected != null)
EditorGUIUtility.PingObject(selected);
}
public void UpdateAsset()
{
if (selected != null && inMemoryAsset != null)
{
var path = AssetDatabase.GetAssetPath(selected);
if (string.IsNullOrEmpty(path) || inMemoryAsset == null)
{
return;
}
var masterNode = ((MaterialGraphAsset)inMemoryAsset).materialGraph.masterNode;
if (masterNode == null)
return;
List<PropertyGenerator.TextureInfo> configuredTextures;
masterNode.GetFullShader(GenerationMode.ForReals, "NotNeeded", out configuredTextures);
var shaderImporter = AssetImporter.GetAtPath(path) as ShaderImporter;
if (shaderImporter == null)
return;
var textureNames = new List<string>();
var textures = new List<Texture>();
foreach (var textureInfo in configuredTextures.Where(
x => x.modifiable == TexturePropertyChunk.ModifiableState.Modifiable))
{
var texture = EditorUtility.InstanceIDToObject(textureInfo.textureId) as Texture;
if (texture == null)
continue;
textureNames.Add(textureInfo.name);
textures.Add(texture);
}
shaderImporter.SetDefaultTextures(textureNames.ToArray(), textures.ToArray());
textureNames.Clear();
textures.Clear();
foreach (var textureInfo in configuredTextures.Where(
x => x.modifiable == TexturePropertyChunk.ModifiableState.NonModifiable))
{
var texture = EditorUtility.InstanceIDToObject(textureInfo.textureId) as Texture;
if (texture == null)
continue;
textureNames.Add(textureInfo.name);
textures.Add(texture);
}
shaderImporter.SetNonModifiableTextures(textureNames.ToArray(), textures.ToArray());
File.WriteAllText(path, EditorJsonUtility.ToJson(inMemoryAsset.graph));
shaderImporter.SaveAndReimport();
AssetDatabase.ImportAsset(path);
}
}
public virtual void ToggleRequiresTime()
{
allowAlwaysRepaint = !allowAlwaysRepaint;
}
public void ChangeSelction(Object newSelection)
{
if (!EditorUtility.IsPersistent (newSelection))
return;
if (selected == newSelection)
return;
if (selected != null)
{
if (EditorUtility.DisplayDialog ("Save Old Graph?", "Save Old Graph?", "yes!", "no")) {
UpdateAsset ();
}
}
selected = newSelection;
var mGraph = CreateInstance<MaterialGraphAsset>();
var path = AssetDatabase.GetAssetPath(newSelection);
var textGraph = File.ReadAllText(path, Encoding.UTF8);
mGraph.materialGraph = JsonUtility.FromJson<UnityEngine.MaterialGraph.MaterialGraph>(textGraph);
inMemoryAsset = mGraph;
var graph = inMemoryAsset.graph;
graph.OnEnable ();
graph.ValidateGraph ();
var source = CreateDataSource ();
source.Initialize (inMemoryAsset, this) ;
m_GraphEditorDrawer.presenter = source;
//m_GraphView.StretchToParentSize();
Repaint ();
/*if (refocus)
{
focused = false;
m_GraphEditorDrawer.graphView.Schedule (Focus).StartingIn (1).Until (() => focused);
}*/
}
public void OnBeforeSerialize()
{
//m_ToLoad = m_Selected as ScriptableObject;
}
public void OnAfterDeserialize()
{}
/*
private void ConvertSelectionToSubGraph()
{
if (m_Canvas.presenter == null)
return;
var presenter = m_Canvas.presenter as GraphDataSource;
if (presenter == null)
return;
var asset = presenter.graphAsset;
if (asset == null)
return;
var targetGraph = asset.graph;
if (targetGraph == null)
return;
if (!m_Canvas.selection.Any())
return;
var serialzied = CopySelected.SerializeSelectedElements(m_Canvas);
var deserialized = CopySelected.DeserializeSelectedElements(serialzied);
if (deserialized == null)
return;
string path = EditorUtility.SaveFilePanelInProject("Save subgraph", "New SubGraph", "ShaderSubGraph", "");
path = path.Replace(Application.dataPath, "Assets");
if (path.Length == 0)
return;
var graphAsset = CreateInstance<MaterialSubGraphAsset>();
graphAsset.name = Path.GetFileName(path);
graphAsset.PostCreate();
var graph = graphAsset.subGraph;
if (graphAsset.graph == null)
return;
var nodeGuidMap = new Dictionary<Guid, Guid>();
foreach (var node in deserialized.GetNodes<INode>())
{
var oldGuid = node.guid;
var newGuid = node.RewriteGuid();
nodeGuidMap[oldGuid] = newGuid;
graph.AddNode(node);
}
// remap outputs to the subgraph
var inputEdgeNeedsRemap = new List<IEdge>();
var outputEdgeNeedsRemap = new List<IEdge>();
foreach (var edge in deserialized.edges)
{
var outputSlot = edge.outputSlot;
var inputSlot = edge.inputSlot;
Guid remappedOutputNodeGuid;
Guid remappedInputNodeGuid;
var outputRemapExists = nodeGuidMap.TryGetValue(outputSlot.nodeGuid, out remappedOutputNodeGuid);
var inputRemapExists = nodeGuidMap.TryGetValue(inputSlot.nodeGuid, out remappedInputNodeGuid);
// pasting nice internal links!
if (outputRemapExists && inputRemapExists)
{
var outputSlotRef = new SlotReference(remappedOutputNodeGuid, outputSlot.slotId);
var inputSlotRef = new SlotReference(remappedInputNodeGuid, inputSlot.slotId);
graph.Connect(outputSlotRef, inputSlotRef);
}
// one edge needs to go to outside world
else if (outputRemapExists)
{
inputEdgeNeedsRemap.Add(edge);
}
else if (inputRemapExists)
{
outputEdgeNeedsRemap.Add(edge);
}
}
// we do a grouping here as the same output can
// point to multiple inputs
var uniqueOutputs = outputEdgeNeedsRemap.GroupBy(edge => edge.outputSlot);
var inputsNeedingConnection = new List<KeyValuePair<IEdge, IEdge>>();
foreach (var group in uniqueOutputs)
{
var inputNode = graph.inputNode;
var slotId = inputNode.AddSlot();
var outputSlotRef = new SlotReference(inputNode.guid, slotId);
foreach (var edge in group)
{
var newEdge = graph.Connect(outputSlotRef, new SlotReference(nodeGuidMap[edge.inputSlot.nodeGuid], edge.inputSlot.slotId));
inputsNeedingConnection.Add(new KeyValuePair<IEdge, IEdge>(edge, newEdge));
}
}
var uniqueInputs = inputEdgeNeedsRemap.GroupBy(edge => edge.inputSlot);
var outputsNeedingConnection = new List<KeyValuePair<IEdge, IEdge>>();
foreach (var group in uniqueInputs)
{
var outputNode = graph.outputNode;
var slotId = outputNode.AddSlot();
var inputSlotRef = new SlotReference(outputNode.guid, slotId);
foreach (var edge in group)
{
var newEdge = graph.Connect(new SlotReference(nodeGuidMap[edge.outputSlot.nodeGuid], edge.outputSlot.slotId), inputSlotRef);
outputsNeedingConnection.Add(new KeyValuePair<IEdge, IEdge>(edge, newEdge));
}
}
AssetDatabase.CreateAsset(graphAsset, path);
var subGraphNode = new SubGraphNode();
targetGraph.AddNode(subGraphNode);
subGraphNode.subGraphAsset = graphAsset;
foreach (var edgeMap in inputsNeedingConnection)
{
targetGraph.Connect(edgeMap.Key.outputSlot, new SlotReference(subGraphNode.guid, edgeMap.Value.outputSlot.slotId));
}
foreach (var edgeMap in outputsNeedingConnection)
{
targetGraph.Connect(new SlotReference(subGraphNode.guid, edgeMap.Value.inputSlot.slotId), edgeMap.Key.inputSlot);
}
var toDelete = m_Canvas.selection.Where(x => x is DrawableNode).ToList();
presenter.DeleteElements(toDelete);
targetGraph.ValidateGraph();
m_Canvas.ReloadData();
m_Canvas.Invalidate();
m_Canvas.selection.Clear();
var toSelect = m_Canvas.elements.OfType<DrawableNode>().FirstOrDefault(x => x.m_Node == subGraphNode);
if (toSelect != null)
{
toSelect.selected = true;
m_Canvas.selection.Add(toSelect);
}
m_Canvas.Repaint();
}*/
}
}

17
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/GraphEditWindow.cs


using UnityEngine;
using UnityEngine.Graphing;
namespace UnityEditor.Graphing.Drawing
{
public class GraphEditWindow : AbstractGraphEditWindow
{
public override IGraphAsset inMemoryAsset { get; set; }
public override Object selected { get; set; }
public GraphEditWindow(string path)
{
}
}
}

150
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/SerializableGraphView.cs


using System.Collections.Generic;
using System.Linq;
using UnityEditor.Experimental.UIElements.GraphView;
using UnityEngine;
using UnityEngine.Experimental.UIElements;
namespace UnityEditor.Graphing.Drawing
{
// TODO JOCE Maybe bring SimpleGraphView public. This implements pretty much all that it does.
public class SerializableGraphView : GraphView
{
private ShortcutHandler m_ShortcutHandler;
private EditorWindow m_EditorWindow;
public SerializableGraphView(EditorWindow editorWindow)
{
m_EditorWindow = editorWindow;
m_ShortcutHandler = new ShortcutHandler(
new Dictionary<Event, ShortcutDelegate>
{
{Event.KeyboardEvent("a"), FrameAll},
{Event.KeyboardEvent("f"), FrameSelection},
{Event.KeyboardEvent("o"), FrameOrigin},
{Event.KeyboardEvent("delete"), DeleteSelection},
{Event.KeyboardEvent("#tab"), FramePrev},
{Event.KeyboardEvent("tab"), FrameNext},
{Event.KeyboardEvent("#c"), CopySelection},
{Event.KeyboardEvent("#v"), Paste},
{Event.KeyboardEvent("#d"), DuplicateSelection}
});
onEnter += () => m_EditorWindow.rootVisualContainer.parent.AddManipulator(m_ShortcutHandler);
onLeave += () => m_EditorWindow.rootVisualContainer.parent.RemoveManipulator(m_ShortcutHandler);
this.AddManipulator(new Commandable
{
{ "Duplicate", () => true, () => Debug.Log("Duplicate!") },
{ "Copy", () => true, () => Debug.Log("Copy!") }
});
this.AddManipulator(new ClickGlobalSelector());
this.AddManipulator(new ContentZoomer());
this.AddManipulator(new ContentDragger());
this.AddManipulator(new RectangleSelector());
this.AddManipulator(new SelectionDragger());
this.AddManipulator(new ClickSelector());
Insert(0, new GridBackground());
typeFactory[typeof(GraphNodePresenter)] = typeof(NodeDrawer);
}
// TODO JOCE Remove the "new" here. Use the base class' impl
private new EventPropagation DeleteSelection()
{
var nodalViewData = GetPresenter<AbstractGraphPresenter>();
if (nodalViewData == null)
return EventPropagation.Stop;
nodalViewData.RemoveElements(
selection.OfType<NodeDrawer>().Select(x => x.GetPresenter<GraphNodePresenter>()),
selection.OfType<Edge>().Select(x => x.GetPresenter<GraphEdgePresenter>())
);
return EventPropagation.Stop;
}
public override void OnDataChanged()
{
base.OnDataChanged();
var graphDataSource = GetPresenter<AbstractGraphPresenter>();
if (graphDataSource == null)
return;
var graphAsset = graphDataSource.graphAsset;
if (graphAsset == null || graphAsset.drawingData.selection.SequenceEqual(selection.OfType<NodeDrawer>().Select(d => ((GraphNodePresenter) d.presenter).node.guid))) return;
var selectedDrawers = graphDataSource.graphAsset.drawingData.selection
.Select(guid => contentViewContainer
.OfType<NodeDrawer>()
.FirstOrDefault(drawer => ((GraphNodePresenter) drawer.presenter).node.guid == guid))
.ToList();
ClearSelection();
foreach (var drawer in selectedDrawers)
AddToSelection(drawer);
}
public void SetGlobalSelection()
{
var graphDataSource = GetPresenter<AbstractGraphPresenter>();
if (graphDataSource == null || graphDataSource.graphAsset == null)
return;
//Selection.activeObject = graphDataSource.graphAsset.GetScriptableObject();
}
private void PropagateSelection()
{
var graphDataSource = GetPresenter<AbstractGraphPresenter>();
if (graphDataSource == null || graphDataSource.graphAsset == null)
return;
var selectedNodeGuids = selection.OfType<NodeDrawer>().Select(x => ((GraphNodePresenter) x.presenter).node.guid);
graphDataSource.graphAsset.drawingData.selection = selectedNodeGuids;
}
public override void AddToSelection(ISelectable selectable)
{
base.AddToSelection(selectable);
PropagateSelection();
}
public override void RemoveFromSelection(ISelectable selectable)
{
base.RemoveFromSelection(selectable);
PropagateSelection();
}
public override void ClearSelection()
{
base.ClearSelection();
PropagateSelection();
}
public EventPropagation CopySelection()
{
var graphDataSource = GetPresenter<AbstractGraphPresenter>();
if (selection.Any() && graphDataSource != null)
graphDataSource.Copy(selection.OfType<GraphElement>().Select(ge => ge.presenter));
return EventPropagation.Stop;
}
public EventPropagation DuplicateSelection()
{
var graphDataSource = GetPresenter<AbstractGraphPresenter>();
if (selection.Any() && graphDataSource != null)
graphDataSource.Duplicate(selection.OfType<GraphElement>().Select(ge => ge.presenter));
return EventPropagation.Stop;
}
public EventPropagation Paste()
{
var graphDataSource = GetPresenter<AbstractGraphPresenter>();
if (graphDataSource != null)
graphDataSource.Paste();
return EventPropagation.Stop;
}
}
}
正在加载...
取消
保存