Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Resolved GraphView: Inheriting from Port to store custom data

Discussion in 'UI Toolkit' started by FeXseven, Aug 25, 2021.

  1. FeXseven

    FeXseven

    Joined:
    Feb 13, 2016
    Posts:
    16
    I recently stumbled upon this awesome experimental GraphView package and I started playing around with it.

    I was wondering if it is possible to inherit from Port class and use the inherited class to store additional data just like you can inherit from Node.
    Usually, adding a new port works like this:

    Code (CSharp):
    1. Port port = InstantiatePort(Orientation.Horizontal, Direction.Input, Port.Capacity.Single, slot.DataType);
    but when just using
    Code (CSharp):
    1. MyCustomPort port = new MyCustomPort(...);
    2. inputContainer.Add(port)
    then I cannot connect any edge (it just disappears when dropping).
    So I looked into the source code on https://github.com/Unity-Technologi...ster/Modules/GraphViewEditor/Elements/Port.cs and realized that the manipulator for edge connection is missing when just initializing a Port by constructor.
    So I replicated the steps which have been done in that repository, only to realize that port does not have a definition for
    AddManipulator


    Is there any way to have custom ports or at least store custom data in a port?
     
  2. FeXseven

    FeXseven

    Joined:
    Feb 13, 2016
    Posts:
    16
    Okay apparently I was just missing the import for UIElements and Visual Studio did not show this in quick actions. By adding the import manually, the
    AddManipulator
    function works.

    However I find it a little weird that inheriting from a port involves manually adding manipulators. Did I do something wrong?
     
  3. Merikles

    Merikles

    Joined:
    Dec 31, 2018
    Posts:
    2
    Ports like Nodes are VisualElements and therefore you should be able to just add the UI components you need through

    Code (CSharp):
    1. Port port = InstantiatePort(Orientation.Horizontal, Direction.Input, Port.Capacity.Single, type);
    2. TextField textField = new TextField();
    3. port.Add(textField);
    My take-away from how Ports are initialized is that they are components not supposed to live in a custom inheritance hierarchy (composition+configuration instead of inheritance).
     
    Last edited: May 18, 2022
  4. Nightmare34

    Nightmare34

    Joined:
    Oct 3, 2020
    Posts:
    7
    I have issue, i can't connect edge, when i click on the port connector nothing happens.
    A google search send me here. Man you save me !
    You need to copy past the private class DefaultEdgeConnectorListener from https://github.com/Unity-Technologi...ster/Modules/GraphViewEditor/Elements/Port.cs
    then
    Code (CSharp):
    1.  
    2. public DialogueChoicePort (DialogueNode pNode, DialogueGraphView pGraphView, string pDialogueText, bool pIsDisplayed, string pOverridenPortName = "") : base(Orientation.Horizontal, Direction.Output, Capacity.Single, typeof(bool))
    3.         {
    4.             string lCount = (pNode.outputContainer.Query("connector").ToList().Count + 1).ToString();
    5.             _dialogueText = string.IsNullOrEmpty(pDialogueText)? $"Text{lCount}" : pDialogueText;
    6.             _isdisplayed = pIsDisplayed;
    7.             string lChoicePortName = string.IsNullOrEmpty(pOverridenPortName) ? $"{ChoicePortRadicalName}{lCount}" : pOverridenPortName;
    8.             portName = lChoicePortName;
    9.  
    10.             TextField lChoiceTextField = new()
    11.             {
    12.                 name = string.Empty,
    13.                 value = _dialogueText
    14.             };
    15.             lChoiceTextField.RegisterValueChangedCallback(lEvt => _dialogueText = lEvt.newValue);
    16.             contentContainer.Add(lChoiceTextField);
    17.  
    18.             Button lDeletePortButton = new(() => pGraphView.RemovePort(pNode,this)) { text = "x" };
    19.             contentContainer.Add(lDeletePortButton);
    20.             pNode.outputContainer.Add(this);
    21.             pNode.RefreshExpandedState();
    22.             pNode.RefreshPorts();
    23.  
    24.             var connectorListener = new DefaultEdgeConnectorListener();
    25.             m_EdgeConnector = new EdgeConnector<Edge>(connectorListener);
    26.             this.AddManipulator(m_EdgeConnector);
    27.         }
    28.  
    Magic :) !
    Code (CSharp):
    1.  //this is a GraphView class
    2. DialogueChoicePort pPort = new(pNode, this, pDialogText, pIsdisplayed, pOverridenPortName);