浏览代码

- Dropping edge on graph (specifically not on a slot) now pops up the add node menu and auto-connects to the first compatible slot (only shows nodes where a slot is compatible)

- Another repaint to fix issue where an added node is not shown
- Update ports and colors when deleting nodes per graphview's request
/main
Peter Bay Bastian 7 年前
当前提交
8c82d94e
共有 3 个文件被更改,包括 104 次插入33 次删除
  1. 8
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/EdgeConnectorListener.cs
  2. 95
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/SearchWindowProvider.cs
  3. 34
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/GraphEditorView.cs

8
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/EdgeConnectorListener.cs


public class EdgeConnectorListener : IEdgeConnectorListener
{
readonly AbstractMaterialGraph m_Graph;
readonly SearchWindowProvider m_SearchWindowProvider;
public EdgeConnectorListener(AbstractMaterialGraph graph)
public EdgeConnectorListener(AbstractMaterialGraph graph, SearchWindowProvider searchWindowProvider)
m_SearchWindowProvider = searchWindowProvider;
var draggedPort = (edge.output != null ? edge.output.edgeConnector.edgeDragHelper.draggedPort : null) ?? (edge.input != null ? edge.input.edgeConnector.edgeDragHelper.draggedPort : null);
m_SearchWindowProvider.connectedPort = draggedPort;
SearchWindow.Open(new SearchWindowContext(GUIUtility.GUIToScreenPoint(Event.current.mousePosition)), m_SearchWindowProvider);
}
public void OnDrop(GraphView graphView, Edge edge)

if (leftSlot != null && rightSlot != null)
{
m_Graph.owner.RegisterCompleteObjectUndo("Connect Edge");
m_Graph.Connect(leftSlot.slotReference, rightSlot.slotReference);
}
}

95
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/SearchWindowProvider.cs


AbstractMaterialGraph m_Graph;
GraphView m_GraphView;
Texture2D m_Icon;
public Port connectedPort { get; set; }
public void Initialize(EditorWindow editorWindow, AbstractMaterialGraph graph, GraphView graphView)
{

}
}
struct NestedEntry
struct NodeEntry
public object userData;
public AbstractMaterialNode node;
public int compatibleSlotId;
List<ISlot> m_Slots = new List<ISlot>();
var nestedEntries = new List<NestedEntry>();
var nodeEntries = new List<NodeEntry>();
foreach (var type in Assembly.GetAssembly(typeof(AbstractMaterialNode)).GetTypes())
{
if (type.IsClass && !type.IsAbstract && (type.IsSubclassOf(typeof(AbstractMaterialNode))))

nestedEntries.Add(new NestedEntry { title = attrs[0].title, userData = type });
{
var node = (AbstractMaterialNode) Activator.CreateInstance(type);
var compatibleSlotId = -1;
if (connectedPort != null)
{
compatibleSlotId = GetFirstCompatibleSlotId(node);
if (compatibleSlotId == -1)
continue;
}
nodeEntries.Add(new NodeEntry { title = attrs[0].title, node = node, compatibleSlotId = compatibleSlotId});
}
}
}

nestedEntries.Add(new NestedEntry
var node = Activator.CreateInstance<SubGraphNode>();
node.subGraphAsset = asset;
var compatibleSlotId = -1;
if (connectedPort != null)
{
compatibleSlotId = GetFirstCompatibleSlotId(node);
if (compatibleSlotId == -1)
continue;
}
nodeEntries.Add(new NodeEntry
userData = asset
node = node,
compatibleSlotId = compatibleSlotId
});
}

// - Art/Adjustments/ColorBalance
// - Art/Adjustments/Contrast
nestedEntries.Sort((entry1, entry2) =>
nodeEntries.Sort((entry1, entry2) =>
{
for (var i = 0; i < entry1.title.Length; i++)
{

new SearchTreeGroupEntry(new GUIContent("Create Node"), 0),
};
foreach (var nestedEntry in nestedEntries)
foreach (var nodeEntry in nodeEntries)
for (var i = 0; i < nestedEntry.title.Length - 1; i++)
for (var i = 0; i < nodeEntry.title.Length - 1; i++)
var group = nestedEntry.title[i];
var group = nodeEntry.title[i];
if (i >= groups.Count)
{
// The current group path matches a prefix of the current entry's group path, so we add the

// Create new group entries as needed.
// If we don't need to modify the group path, `createIndex` will be `int.MaxValue` and thus the loop won't run.
for (var i = createIndex; i < nestedEntry.title.Length - 1; i++)
for (var i = createIndex; i < nodeEntry.title.Length - 1; i++)
var group = nestedEntry.title[i];
var group = nodeEntry.title[i];
tree.Add(new SearchTreeEntry(new GUIContent(nestedEntry.title.Last(), m_Icon)) { level = nestedEntry.title.Length, userData = nestedEntry.userData });
tree.Add(new SearchTreeEntry(new GUIContent(nodeEntry.title.Last(), m_Icon)) { level = nodeEntry.title.Length, userData = nodeEntry });
int GetFirstCompatibleSlotId(AbstractMaterialNode node)
{
var connectedSlot = (MaterialSlot)connectedPort.userData;
m_Slots.Clear();
node.GetSlots(m_Slots);
foreach (var slot in m_Slots)
{
var materialSlot = (MaterialSlot)slot;
if (materialSlot.IsCompatibleWith(connectedSlot))
{
return materialSlot.id;
}
}
return -1;
}
Type type;
var asset = entry.userData as MaterialSubGraphAsset;
if (asset != null)
type = typeof(SubGraphNode);
else
type = (Type)entry.userData;
var node = Activator.CreateInstance(type) as INode;
if (node == null)
return false;
var nodeEntry = (NodeEntry)entry.userData;
var node = nodeEntry.node;
var drawState = node.drawState;
var windowMousePosition = context.screenMousePosition - m_EditorWindow.position.position;

if (asset != null)
m_Graph.owner.RegisterCompleteObjectUndo("Add " + node.name);
m_Graph.AddNode(node);
if (connectedPort != null)
var subgraphNode = (SubGraphNode)node;
subgraphNode.subGraphAsset = asset;
var connectedSlot = (MaterialSlot)connectedPort.userData;
var connectedSlotReference = connectedSlot.owner.GetSlotReference(connectedSlot.id);
var compatibleSlotReference = node.GetSlotReference(nodeEntry.compatibleSlotId);
var fromReference = connectedSlot.isOutputSlot ? connectedSlotReference : compatibleSlotReference;
var toReference = connectedSlot.isOutputSlot ? compatibleSlotReference : connectedSlotReference;
m_Graph.Connect(fromReference, toReference);
m_Graph.owner.RegisterCompleteObjectUndo("Add " + node.name);
m_Graph.AddNode(node);
return true;
}

34
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/GraphEditorView.cs


m_GraphView = new MaterialGraphView(graph) { name = "GraphView", persistenceKey = "MaterialGraphView" };
m_GraphView.SetupZoom(ContentZoomer.DefaultMinScale, ContentZoomer.DefaultMaxScale);
m_GraphView.AddManipulator(new ContentDragger());
m_GraphView.AddManipulator(new RectangleSelector());
m_GraphView.AddManipulator(new RectangleSelector());
m_GraphView.AddManipulator(new ClickSelector());
m_GraphView.AddManipulator(new GraphDropTarget(graph));
content.Add(m_GraphView);

m_SearchWindowProvider = ScriptableObject.CreateInstance<SearchWindowProvider>();
m_SearchWindowProvider.Initialize(editorWindow, m_Graph, m_GraphView);
m_GraphView.nodeCreationRequest = (c) => SearchWindow.Open(new SearchWindowContext(c.screenMousePosition), m_SearchWindowProvider);
m_GraphView.nodeCreationRequest = (c) =>
{
m_SearchWindowProvider.connectedPort = null;
SearchWindow.Open(new SearchWindowContext(c.screenMousePosition), m_SearchWindowProvider);
};
m_EdgeConnectorListener = new EdgeConnectorListener(m_Graph);
m_EdgeConnectorListener = new EdgeConnectorListener(m_Graph, m_SearchWindowProvider);
foreach (var node in graph.GetNodes<INode>())
AddNode(node);

}
}
var nodesToUpdate = m_NodeViewHashSet;
nodesToUpdate.Clear();
foreach (var edge in graphViewChange.elementsToRemove.OfType<Edge>())
{
if (edge.input != null)
{
var materialNodeView = edge.input.node as MaterialNodeView;
if (materialNodeView != null)
nodesToUpdate.Add(materialNodeView);
}
if (edge.output != null)
{
var materialNodeView = edge.output.node as MaterialNodeView;
if (materialNodeView != null)
nodesToUpdate.Add(materialNodeView);
}
}
foreach (var node in nodesToUpdate)
node.UpdatePortInputVisibilities();
UpdateEdgeColors(nodesToUpdate);
return graphViewChange;
}

m_GraphView.AddElement(nodeView);
nodeView.Initialize(node as AbstractMaterialNode, m_PreviewManager, m_EdgeConnectorListener);
node.onModified += OnNodeChanged;
nodeView.Dirty(ChangeType.Repaint);
}
Edge AddEdge(IEdge edge)

正在加载...
取消
保存