Unity Dialogue System - Removing port connections (Edges)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
If you remember from when we've  finished deleting our groups, we weren't yet able to delete our Edges. This is true either through trying to delete them  through the contextual menu or the delete key, but also true if you delete  a node with a connected port. If you try to do that, our  Edges will still be there. Of course, this shouldn't happen as otherwise  if we connect a node once, that node will always have a connection to another node even if we don't want it to anymore. We'll have to delete them in  three different situations: The first one will be to remove the edges when we select them and choose the delete action. The second one will be when we delete  a node and that node has connections, as they will then need to be removed. The third one will be by adding our custom contextual menus to the node and allow us to choose to disconnect all input ports or output ports, as the node already contains one provided option to disconnect all ports regardless of them being input or output. Let's start with the first one by  going into our GraphView script and to our OnElementsDeleted callback. In here, we'll simply add the edges to a list and  delete them using the "DeleteElements" method. The reason why we're using the "DeleteElements"  method is because the GraphView itself does not have the "RemoveElements" method and we don't really need to do anything else than remove the edges, so  we don't need to iterate through them. So start by creating a new variable of type "Type", to which I'll name edgeType and  give it the value of "typeof(Edge)". Then, create a new "List<Edge>" and I'll  name it "edgesToDelete" and initialize the list. Between our two if statements  we'll create another one to check if the type of the element is of edge type so type in "if (element.getType() == edgeType)" and inside we'll create a new variable  of type "Edge", to which I'll name "edge" and assign the casted element to it. Then, we add this variable  to the "edgesToDelete" list. Don't forget to continue to  the next element at the end. Then, right after our "groupsToDelete" foreach, we delete our edges by typing in "DeleteElements(edgesToDelete)". If we save and go back to Unity, we should now be able to delete our edges through the  contextual menu or the delete key. Of course, they will still stay there  if we simply delete the connected nodes. To fix that we'll be creating a method in  our node script that disconnects its ports. In that method we'll simply iterate through the  node ports and if that specific port is connected, we will remove all the port connections  by using the "DeleteElements" method. This method will also be useful for us later  on because it adds the edges that will be deleted to a certain GraphView variable, which we will need later on in the series. So let's go to our "DSNode" script and above our error style methods we'll create  a new private method called "DisconnectPorts". We'll be able to both disconnect our input and output ports which are placed within different containers, so we'll also accept which container we want to iterate through. So create a parameter of type  "VisualElement" and name it "container". I'll make this method part of a  region called "Utility Methods" and add the style methods to this region as well. Then, we'll have to iterate through the container ports. Thankfully, we know that in our system we  only have ports in the containers we're going to pass in, which are the provided inputContainer and outputContainer, so we can transform the element to a  Port type in our foreach right away. So type in "foreach (Port port in container.Children())". This will get all the elements inside of this container and we're now iterating through the ports of  either the inputContainer or the outputContainer. If you do have any other elements  in this container you would need to check if the element was of  type "Port" and then cast it. Then, we'll need to check if the port  is connected, because if it isn't, then we don't really need to disconnect it. Thankfully, Unity does have a variable  named "connected" in the Port class, so simply type in "if(port.connected)" and  add the "!" (not) operator at the beginning for it to become "not connected", we can then "continue". Otherwise, if it is connected, we will  then need to delete all of its connections. We can do that using the "connections"  variable the Port class also provides. So type in "graphView.DeleteElements(port.connections)". If you prefer to make them into a variable,  you can simply initialize a new list and pass in the "port.connections"  variable to the list constructor, as it will create a list  with those elements in it. I'll leave it as is. Of course, this method is private so  we can't call it in our Graph View. What we'll do is create another public method  that calls our "DisconnectPorts" twice, once per container. So create a new method above by typing in  "public void DisconnectAllPorts()" and inside call "DisconnectPorts(inputContainer)" and then call it again and pass in outputContainer. The method is now done so we simply need  to call it whenever we delete a node. So back to our GraphView script  in our "nodesToDelete" foreach, we'll disconnect all the node ports  before the node is removed from the graph so above our "RemoveElement" method we  type in "node.DisconnectAllPorts()". If we now save and go to Unity, the node edges should now be removed whenever one  of the connected nodes is removed. The disconnection and removal of edges are done but I would also like to add a right  click menu only for our nodes that allows us to disconnect either the input or the output ports. If you right click in a node you can see  that a "Disconnect All" option already exists and works pretty well. This option is provided by Unity but we  can also add our own, which we will do. Going back to our DSNode script we are able  to add our own contextual menu to the node by overriding a method called "BuildContextualMenu", so press "Alt + Enter" and go to "Generate overrides..." and click "Deselect All". Then, go to the bottom where you will find the "BuildContextualMenu" method  and select it and press "OK". I'll make this method be part of a  new region named "Overrided Methods". If you were the remove this base  method call it would still work, but I'll leave it here just  to make sure it works properly as there might be something not working  that we're not seeing if we remove it. Next, we'll have to create two menu  actions to disconnect the ports. If you create the actions above our base  method call, they will show up in the same menu section as the "Disconnect All" option. If you were to create them under our base method call, they would show up in the  "Cut, Copy and Paste" menu section. I will be adding them above our base method call. To do that, we will be using the same  method we used in our contextual menu, which is the "AppendAction" method, in which we can access through typing in "evt.menu.AppendAction()" and in here we'll need  to pass in the name of the menu and its action, so type in "Disconnect Input Ports" for our name  and an "actionEvent" callback which will disconnect the node through the "DisconnectPorts(inputContainer)". Then, copy and paste the code above and swap  the "Input" parts with "Output" instead. Of course, we're now repeating our "DisconnectPorts" method with the containers twice so I'll create two  new methods, one for each container. So type in "private void DisconnectInputPorts()" and pass in the same code line as we have above that calls the "DisconnectPorts"  with the inputContainer. Feel free to swap this method with  the other two input container calls. Next, we'll do the same for our  outputContainer so copy the method above and simply swap the "Input" part with "Output". Feel free to swap this method with  the output container calls as well. You can make these methods public if you want but I won't be calling them outside of this  script so I'll leave them as private. If we save and go to Unity, right clicking in our nodes and in our nodes only  should show the two new options. Clicking on them should also  disconnect all connected ports. You could disable the options if  there were no ports by iterating through the containers and if there were no  connected ports, set its status as disable in the third "AppendAction" parameter, but I'll leave it as is as we're already checking if the port is connected  in our "DisconnectPorts" method, so no errors will happen if we click on the actions.
Info
Channel: Indie Wafflus
Views: 228
Rating: undefined out of 5
Keywords: Unity Dialogue System, Unity Dialog System, Unity Graph View, Unity Node, Unity UI Toolkit, Unity Dialogues, Unity Node Based Dialogue System, Dialogue System, Node Based Dialogue System, Unity Dialogs, Unity Visual Elements, Node System, Dialogue System Tutorial, Unity 2D, Unity, Unity Tutorial, Unity Dialogue System Tutorial, Unity 3D, Unity3D, Unity2D
Id: GSCY27EFR3s
Channel Id: undefined
Length: 10min 15sec (615 seconds)
Published: Fri Sep 03 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.