Search Unity

Question Experimental graphView : Cannot open SearchWindow when Edge dropped outside a Port

Discussion in 'Scripting' started by Quasar47, Jul 28, 2021.

  1. Quasar47

    Quasar47

    Joined:
    Mar 24, 2017
    Posts:
    122
    Hey there, I'm working on a Dialogue Node System using Unity's experimental GraphView library and I've created a simple SearchWindow to instantiate custom Nodes and Groups when the space key or right click is pressed. I would like to know if it was possible to open the SearchWindow when the user drops an Edge outside a Port, just like in Unity's Shader Graph ?

    I know the GraphView has some callbacks to automate some simple commands like that, that's how I used the callback "nodeCreationRequest" to open the window with a single click, but are there callbacks for edges ? If so, how to override them ? I've seen the EdgeConnector class has some callbacks from an interface but they're inaccessible.

    Thank you for your help.
     
  2. MaNaRz

    MaNaRz

    Joined:
    Aug 24, 2017
    Posts:
    117
    @Quasar47 Where you ever able to solve this problem? I want to implement the same thing and am stuck at the exact same place as you were. Any hints would help.
     
  3. Quasar47

    Quasar47

    Joined:
    Mar 24, 2017
    Posts:
    122
    Hello,
    Unfortunately, no. I eventually had to ship my tool, and so I had to drop the issue after a few tries.
    Sorry for now being able to be helpful. If you ever find a workaround to this problem, feel free to post it here so that others don't have to lookup for themselves.
     
  4. Tauntastic

    Tauntastic

    Joined:
    Sep 24, 2020
    Posts:
    17
    I figured this out.

    So the movable ghost edge does not exist in
    GraphView
    , but exists in the
    Node > Port
    side.
    Port 
    has overridable methods called
    OnStartEdgeDragging()
    and
    OnStopEdgeDragging()
    .

    What you need to do is create a
    PortView
    class that inherits from
    Port
    and create the
    DefaultEdgeConnectorListener
    private class' equivalent.

    Code (CSharp):
    1.  
    2. namespace TG.Frameworks.NodeTrees.Editor
    3. {
    4.     public class PortView : Port
    5.     {
    6.         protected PortView(Orientation portOrientation, Direction portDirection, Capacity portCapacity, Type type) : base(portOrientation, portDirection, portCapacity, type)
    7.         {
    8.      
    9.         }
    10.  
    11.         public override void OnStartEdgeDragging()
    12.         {
    13.             base.OnStartEdgeDragging();
    14.             Debug.Log("Dragging");
    15.         }
    16.  
    17.         public override void OnStopEdgeDragging()
    18.         {
    19.             base.OnStopEdgeDragging();
    20.             Debug.Log("Stopped Dragging");
    21.         }
    22.  
    23.         public new static Port Create<TEdge>(
    24.             Orientation orientation,
    25.             Direction direction,
    26.             Capacity capacity,
    27.             Type type)
    28.             where TEdge : Edge, new()
    29.         {
    30.             DefaultEdgeConnectorListener listener = new DefaultEdgeConnectorListener();
    31.             PortView ele = new PortView(orientation, direction, capacity, type)
    32.             {
    33.                 m_EdgeConnector = new EdgeConnector<TEdge>(listener)
    34.             };
    35.             ele.AddManipulator(ele.m_EdgeConnector);
    36.             return ele;
    37.         }
    38.  
    39.         private class DefaultEdgeConnectorListener : IEdgeConnectorListener
    40.         {
    41.             private GraphViewChange _graphViewChange;
    42.             private List<Edge> _edgesToCreate;
    43.             private List<GraphElement> _edgesToDelete;
    44.  
    45.             public DefaultEdgeConnectorListener()
    46.             {
    47.                 _edgesToCreate = new List<Edge>();
    48.                 _edgesToDelete = new List<GraphElement>();
    49.                 _graphViewChange.edgesToCreate = _edgesToCreate;
    50.             }
    51.  
    52.             public void OnDropOutsidePort(Edge edge, Vector2 position)
    53.             {
    54.             }
    55.  
    56.             public void OnDrop(GraphView graphView, Edge edge)
    57.             {
    58.                 _edgesToCreate.Clear();
    59.                 _edgesToCreate.Add(edge);
    60.                 _edgesToDelete.Clear();
    61.                 if (edge.input.capacity == Capacity.Single)
    62.                 {
    63.                     foreach (Edge connection in edge.input.connections)
    64.                     {
    65.                         if (connection != edge)
    66.                             _edgesToDelete.Add(connection);
    67.                     }
    68.                 }
    69.  
    70.                 if (edge.output.capacity == Capacity.Single)
    71.                 {
    72.                     foreach (Edge connection in edge.output.connections)
    73.                     {
    74.                         if (connection != edge)
    75.                             _edgesToDelete.Add(connection);
    76.                     }
    77.                 }
    78.  
    79.                 if (_edgesToDelete.Count > 0)
    80.                     graphView.DeleteElements(_edgesToDelete);
    81.                 List<Edge> edgesToCreate = _edgesToCreate;
    82.                 if (graphView.graphViewChanged != null)
    83.                     edgesToCreate = graphView.graphViewChanged(_graphViewChange).edgesToCreate;
    84.                 foreach (Edge edge1 in edgesToCreate)
    85.                 {
    86.                     graphView.AddElement(edge1);
    87.                     edge.input.Connect(edge1);
    88.                     edge.output.Connect(edge1);
    89.                 }
    90.             }
    91.         }
    92.     }
    93. }
    94.  
    You then have to
    override InstantiatePort(...)
    in a class derived from base class
    Node


    Code (CSharp):
    1. public override Port InstantiatePort(Orientation orientation, Direction direction, Port.Capacity capacity, Type type)
    2. {
    3.     return PortView.Create<Edge>(orientation, direction, capacity, type);
    4. }
    Voilà, it prints!
    Edge Start and Stop Dragging.png
     
    Last edited: Dec 19, 2022
  5. MaNaRz

    MaNaRz

    Joined:
    Aug 24, 2017
    Posts:
    117
    Thank you! I just found the "VFXDataAnchor" and I was about to copy it and see if i could get it to work. You saved me tons of time!
     
  6. Tauntastic

    Tauntastic

    Joined:
    Sep 24, 2020
    Posts:
    17
    I was wrong about one thing. For what you want, you'll want to use
    public void OnDropOutsidePort(Edge edge, Vector2 position)
    inside the
    DefaultEdgeConnectorListener
    class I previously posted. This class implements the
    IEdgeConnector
    interface which is the key for this to work.
     
    MaNaRz likes this.