浏览代码

Fix hanging edges (fixes #142, fixes #152, fixes #158)

/main
Peter Bay Bastian 7 年前
当前提交
d41f2281
共有 7 个文件被更改,包括 108 次插入64 次删除
  1. 8
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/EdgeConnectorListener.cs
  2. 8
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/SearchWindowProvider.cs
  3. 15
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/GraphEditorView.cs
  4. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/MaterialGraphView.cs
  5. 101
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/MaterialNodeView.cs
  6. 34
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/ShaderPort.cs
  7. 2
      MaterialGraphProject/ProjectSettings/ProjectVersion.txt

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


namespace UnityEditor.ShaderGraph.Drawing
{
public class EdgeConnectorListener : IEdgeConnectorListener
class EdgeConnectorListener : IEdgeConnectorListener
{
readonly AbstractMaterialGraph m_Graph;
readonly SearchWindowProvider m_SearchWindowProvider;

public void OnDropOutsidePort(Edge edge, Vector2 position)
{
var draggedPort = (edge.output != null ? edge.output.edgeConnector.edgeDragHelper.draggedPort : null) ?? (edge.input != null ? edge.input.edgeConnector.edgeDragHelper.draggedPort : null);
m_SearchWindowProvider.connectedPort = draggedPort;
m_SearchWindowProvider.connectedPort = (ShaderPort) draggedPort;
var leftSlot = edge.output.userData as ISlot;
var rightSlot = edge.input.userData as ISlot;
var leftSlot = edge.output.GetSlot();
var rightSlot = edge.input.GetSlot();
if (leftSlot != null && rightSlot != null)
{
m_Graph.owner.RegisterCompleteObjectUndo("Connect Edge");

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


namespace UnityEditor.ShaderGraph.Drawing
{
public class SearchWindowProvider : ScriptableObject, ISearchWindowProvider
class SearchWindowProvider : ScriptableObject, ISearchWindowProvider
public Port connectedPort { get; set; }
public ShaderPort connectedPort { get; set; }
public bool nodeNeedsRepositioning { get; set; }
public SlotReference targetSlotReference { get; private set; }
public Vector2 targetPosition { get; private set; }

int GetFirstCompatibleSlotId(AbstractMaterialNode node)
{
var connectedSlot = (MaterialSlot)connectedPort.userData;
var connectedSlot = connectedPort.slot;
m_Slots.Clear();
node.GetSlots(m_Slots);
foreach (var slot in m_Slots)

if (connectedPort != null)
{
var connectedSlot = (MaterialSlot)connectedPort.userData;
var connectedSlot = connectedPort.slot;
var connectedSlotReference = connectedSlot.owner.GetSlotReference(connectedSlot.id);
var compatibleSlotReference = node.GetSlotReference(nodeEntry.compatibleSlotId);

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


{
foreach (var edge in graphViewChange.edgesToCreate)
{
var leftSlot = edge.output.userData as ISlot;
var rightSlot = edge.input.userData as ISlot;
var leftSlot = edge.output.GetSlot();
var rightSlot = edge.input.GetSlot();
if (leftSlot != null && rightSlot != null)
{
m_Graph.owner.RegisterCompleteObjectUndo("Connect Edge");

var port = element as ShaderPort;
if (port == null)
continue;
var slot = (MaterialSlot)port.userData;
if (slot.slotReference.Equals(m_SearchWindowProvider.targetSlotReference))
if (port.slot.slotReference.Equals(m_SearchWindowProvider.targetSlotReference))
{
port.RegisterCallback<PostLayoutEvent>(RepositionNode);
return;

var sourceNodeView = m_GraphView.nodes.ToList().OfType<MaterialNodeView>().FirstOrDefault(x => x.node == sourceNode);
if (sourceNodeView != null)
{
var sourceAnchor = sourceNodeView.outputContainer.Children().OfType<Port>().FirstOrDefault(x => x.userData is ISlot && (x.userData as ISlot).Equals(sourceSlot));
var sourceAnchor = sourceNodeView.outputContainer.Children().OfType<ShaderPort>().FirstOrDefault(x => x.slot.Equals(sourceSlot));
var targetAnchor = targetNodeView.inputContainer.Children().OfType<Port>().FirstOrDefault(x => x.userData is ISlot && (x.userData as ISlot).Equals(targetSlot));
var targetAnchor = targetNodeView.inputContainer.Children().OfType<ShaderPort>().FirstOrDefault(x => x.slot.Equals(targetSlot));
var edgeView = new Edge
{

{
foreach (var edgeView in anchorView.connections.OfType<Edge>())
{
var targetSlot = (MaterialSlot)edgeView.input.userData;
var targetSlot = edgeView.input.GetSlot();
if (targetSlot.valueType == SlotValueType.Dynamic)
{
var connectedNodeView = edgeView.input.node as MaterialNodeView;

}
foreach (var anchorView in nodeView.inputContainer.Children().OfType<Port>())
{
var targetSlot = (MaterialSlot)anchorView.userData;
var targetSlot = anchorView.GetSlot();
if (targetSlot.valueType != SlotValueType.Dynamic)
continue;
foreach (var edgeView in anchorView.connections.OfType<Edge>())

4
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/MaterialGraphView.cs


public override List<Port> GetCompatiblePorts(Port startAnchor, NodeAdapter nodeAdapter)
{
var compatibleAnchors = new List<Port>();
var startSlot = startAnchor.userData as MaterialSlot;
var startSlot = startAnchor.GetSlot();
if (startSlot == null)
return compatibleAnchors;

foreach (var candidateAnchor in ports.ToList())
{
var candidateSlot = candidateAnchor.userData as MaterialSlot;
var candidateSlot = candidateAnchor.GetSlot();
if (!startSlot.IsCompatibleWith(candidateSlot))
continue;

101
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/MaterialNodeView.cs


name = "controls"
};
extensionContainer.Add(m_ControlsContainer);
m_ControlsDivider = new VisualElement {name = "divider"};
m_ControlsDivider = new VisualElement { name = "divider" };
m_ControlsDivider.AddToClassList("horizontal");
if (node.hasPreview)

m_PreviewRenderData.onPreviewChanged += UpdatePreviewTexture;
UpdatePreviewTexture();
var collapsePreviewButton = new VisualElement { name = "collapse"};
var collapsePreviewButton = new VisualElement { name = "collapse" };
{
node.owner.owner.RegisterCompleteObjectUndo("Collapse Preview");
UpdatePreviewExpandedState(false);
}));
{
node.owner.owner.RegisterCompleteObjectUndo("Collapse Preview");
UpdatePreviewExpandedState(false);
}));
var expandPreviewButton = new VisualElement { name = "expand"};
expandPreviewButton.Add(new VisualElement { name = "icon"});
var expandPreviewButton = new VisualElement { name = "expand" };
expandPreviewButton.Add(new VisualElement { name = "icon" });
{
node.owner.owner.RegisterCompleteObjectUndo("Expand Preview");
UpdatePreviewExpandedState(true);
}));
{
node.owner.owner.RegisterCompleteObjectUndo("Expand Preview");
UpdatePreviewExpandedState(true);
}));
m_PreviewContainer.Add(expandPreviewButton);
}

m_ControlViews = new List<VisualElement>();
foreach (var propertyInfo in node.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
foreach (IControlAttribute attribute in propertyInfo.GetCustomAttributes(typeof(IControlAttribute), false))
m_ControlViews.Add(attribute.InstantiateControl(node, propertyInfo));
foreach (IControlAttribute attribute in propertyInfo.GetCustomAttributes(typeof(IControlAttribute), false))
m_ControlViews.Add(attribute.InstantiateControl(node, propertyInfo));
m_Attachers = new List<Attacher>(node.GetInputSlots<MaterialSlot>().Count());
AddSlots(node.GetSlots<MaterialSlot>());

UpdatePreviewExpandedState(node.previewExpanded);
base.expanded = node.drawState.expanded;
var anchorsToRemove = inputContainer.Children().ToList();
foreach (var anchorElement in anchorsToRemove)
var inputPorts = inputContainer.Children().OfType<ShaderPort>().ToList();
foreach (var port in inputPorts)
inputContainer.Remove(anchorElement);
var attacher = m_Attachers.FirstOrDefault(a => a.target == anchorElement);
if (attacher != null)
var currentSlot = port.slot;
var newSlot = slots.FirstOrDefault(s => s.id == currentSlot.id);
if (newSlot == null)
{
// Slot doesn't exist anymore, remove it
inputContainer.Remove(port);
// We also need to remove the attacher along with the element it's attaching
var attacher = m_Attachers.FirstOrDefault(a => a.target == port);
if (attacher != null)
{
attacher.Detach();
attacher.element.parent.Remove(attacher.element);
m_Attachers.Remove(attacher);
}
}
else
attacher.Detach();
attacher.element.parent.Remove(attacher.element);
m_Attachers.Remove(attacher);
port.slot = newSlot;
slots.Remove(newSlot);
anchorsToRemove = outputContainer.Children().ToList();
foreach (var ve in anchorsToRemove)
outputContainer.Remove(ve);
foreach (var port in inputContainer.Union(outputContainer).OfType<Port>())
var outputPorts = outputContainer.Children().OfType<ShaderPort>().ToList();
foreach (var port in outputPorts)
var slot = (MaterialSlot)port.userData;
port.portName = slot.displayName;
var currentSlot = port.slot;
var newSlot = slots.FirstOrDefault(s => s.id == currentSlot.id);
if (newSlot == null)
{
outputContainer.Remove(port);
}
else
{
port.slot = newSlot;
slots.Remove(newSlot);
}
slots.Clear();
slots.AddRange(node.GetSlots<MaterialSlot>());
inputContainer.Sort((x, y) => slots.IndexOf(x.userData as MaterialSlot) - slots.IndexOf(y.userData as MaterialSlot));
inputContainer.Sort((x, y) => slots.IndexOf(((ShaderPort)x).slot) - slots.IndexOf(((ShaderPort)y).slot));
outputContainer.Sort((x, y) => slots.IndexOf(x.userData as MaterialSlot) - slots.IndexOf(y.userData as MaterialSlot));
outputContainer.Sort((x, y) => slots.IndexOf(((ShaderPort)x).slot) - slots.IndexOf(((ShaderPort)y).slot));
}
UpdateControls();

if (slot.hidden)
continue;
var port = ShaderPort.Create(Orientation.Horizontal, slot.isInputSlot ? Direction.Input : Direction.Output, null, m_ConnectorListener);
port.portName = slot.displayName;
port.userData = slot;
port.visualClass = slot.concreteValueType.ToClassName();
var port = ShaderPort.Create(slot, m_ConnectorListener);
if (slot.isOutputSlot)
outputContainer.Add(port);
else

void UpdateSlotAttachers()
{
foreach (var port in inputContainer.OfType<Port>())
foreach (var port in inputContainer.OfType<ShaderPort>())
var portInputView = new PortInputView((MaterialSlot)port.userData);
var portInputView = new PortInputView(port.slot);
Add(portInputView);
mainContainer.BringToFront();
m_Attachers.Add(new Attacher(portInputView, port, SpriteAlignment.LeftCenter) { distance = -8f });

{
foreach (var attacher in m_Attachers)
{
var slot = (MaterialSlot)attacher.target.userData;
var slot = ((ShaderPort)attacher.target).slot;
attacher.element.visible = expanded && !node.owner.GetEdges(node.GetSlotReference(slot.id)).Any();
}
}

foreach (var anchor in inputContainer.Concat(outputContainer).OfType<Port>())
foreach (var anchor in inputContainer.Concat(outputContainer).OfType<ShaderPort>())
var slot = (MaterialSlot)anchor.userData;
var slot = anchor.slot;
anchor.portName = slot.displayName;
anchor.visualClass = slot.concreteValueType.ToClassName();
}

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


ShaderPort(Orientation portOrientation, Direction portDirection, Type type)
: base(portOrientation, portDirection, type) { }
public static Port Create(Orientation orientation, Direction direction, Type type, IEdgeConnectorListener connectorListener)
MaterialSlot m_Slot;
public static Port Create(MaterialSlot slot, IEdgeConnectorListener connectorListener)
var port = new ShaderPort(orientation, direction, type)
var port = new ShaderPort(Orientation.Horizontal, slot.isInputSlot ? Direction.Input : Direction.Output, null)
port.slot = slot;
port.portName = slot.displayName;
port.visualClass = slot.concreteValueType.ToClassName();
public VisualElement connectorBox
public MaterialSlot slot
get { return m_ConnectorBox; }
get { return m_Slot; }
set
{
if (ReferenceEquals(value, m_Slot))
return;
if (value == null)
throw new NullReferenceException();
if (m_Slot != null && value.isInputSlot != m_Slot.isInputSlot)
throw new ArgumentException("Cannot change direction of already created port");
m_Slot = value;
portName = slot.displayName;
visualClass = slot.concreteValueType.ToClassName();
}
}
}
static class ShaderPortExtensions
{
public static MaterialSlot GetSlot(this Port port)
{
var shaderPort = port as ShaderPort;
return shaderPort != null ? shaderPort.slot : null;
}
}
}

2
MaterialGraphProject/ProjectSettings/ProjectVersion.txt


m_EditorVersion: 2018.1.0b1
m_EditorVersion: 2018.1.0b4
正在加载...
取消
保存