Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

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:
    117
    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:
    117
    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:
    15
    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:
    15
    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.