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

How to use the new GraphView UIElements?

Discussion in 'Editor & General Support' started by techmage, Jun 18, 2018.

  1. techmage

    techmage

    Joined:
    Oct 31, 2009
    Posts:
    2,133
    I am trying to make a node based editor window with the new GraphView UIElements that the new ShaderGraph is made out of. I've come quite far in understanding how the UIElement tree works and how the style sheets work and all that. I even have empty graph nodes appearing in my empty ShaderGraph.

    But my empty nodes are 1 pixel in height, and stretch the full width of the window. I cannot figure out how to get actual boxes for the nodes to appear that I can then drag around. I have been digging all through the ShaderGraph source with no luck.

    Has anyone managed to get a basic barebones node system working with the new ShaderGraph GraphView system?
     
  2. PallArinbj

    PallArinbj

    Joined:
    Mar 21, 2016
    Posts:
    4
    I'd love to get some basic examples for the GraphView as well.
    I've found no examples for it anywhere on the internet, and Unity says it doesn't have any examples it can share either.

    Would you be willing to post what you have atm? Perhaps someone can build on what you have?

    Edit: Just found out that the Shader Graph system that Unity is building and is currently in preview is, at least partly, built on the GraphView.
    It could perhaps serve as a working foundation to figure out how the GraphView system works.
    https://github.com/Unity-Technologies/ScriptableRenderPipeline/tree/master/com.unity.shadergraph
     
    Last edited: Jun 18, 2018
  3. techmage

    techmage

    Joined:
    Oct 31, 2009
    Posts:
    2,133
  4. PallArinbj

    PallArinbj

    Joined:
    Mar 21, 2016
    Posts:
    4
    Awesome, thanks for sharing.

    Will take a look when I have free time.
     
  5. thylaxene

    thylaxene

    Joined:
    Oct 10, 2005
    Posts:
    716
    Is there any other info out there about UIElements apart from what is available in the manual? Which is pretty thin and the links supplied don't really help beyond the basics. Especially as UIElements was mentioned a few times at Unite Berlin.

    @techmage thanks for the the example I will dissect that as well.
     
  6. techmage

    techmage

    Joined:
    Oct 31, 2009
    Posts:
    2,133
    No. But the UIElements stuff is not really hard to follow. If something doesn't make sense with that feel free to ask me.

    I'm getting to the point where having some more people to run thoughts off of would be rather helpful. Like I am getting to close to severely gutting a lot of the ShaderGraph code to make it generic.

    One thing I just do not get at all is, ShaderGraphs are save as JSON. Like open a .genericGraph shader and it is JSON saved out. Why!? Why does it not go off of ScriptableObject and get serialized to YAML like every other asset? Is it just like severely prototype code that will be refactored? Does anyone know why?

    Right now I am going through and ripping out so much of it to turn it into serializing as a ScriptableObject. I realized this is necessary for what I want it to do.
     
  7. Alverik

    Alverik

    Joined:
    Apr 15, 2016
    Posts:
    417
    Well, I'll likely use this later on. So, if it's not too much to ask... If you get it working as ScriptableObjects let me know how you did it. I'm a little swamped with work so I can't really check it out properly right now... If I get more free time I might jump in and try to help out though, maybe we can trade notes then.
     
  8. techmage

    techmage

    Joined:
    Oct 31, 2009
    Posts:
    2,133
    So I actually set it up to serialize each node via them being ScriptableObjects, got it working that way. Then I realized why it was probably done through JSONUtility initially, and actually have ended up switching the entire thing back to serializing via JSON the same way shadergraph does. The reason is, I think, if each node is a serializedobject then that means you actually have to end up saving each node as an actual file in your project, which is bad. You can compact multiple saved ScriptableObjects into just one file, but still, it means every node would end up being imported as a child of a file in the project file explorer. The way around that is just deal with all the serialization yourself via JSON utility. It actually works good, JSON utility is very efficient. You can also do clever things like serialize one class to JSON, then deserialize than JSON onto another class, and it will populate all the memebers if they are named the same. I ended up relying on this to transfer data from the classes which represents the nodes in the editor, the nodes instanced in the scene actually executing the logic.

    That repo is actually even more developed now. It is really dense though. It would be nice if some highly comfortable digging into it would take up the project with me to sort out all the needed things to make the graphing API generic.
     
    cecarlsen and Alverik like this.
  9. Lentor_Gaming

    Lentor_Gaming

    Joined:
    Feb 24, 2018
    Posts:
    4
    Can you explain a little bit what you are doing here? I can't seem to follow. I'm just trying to figure out how to actually add a GraphView to my EditorWindow.
     
  10. John_Leorid

    John_Leorid

    Joined:
    Nov 5, 2012
    Posts:
    646
    Yea I don't understand anything done here - theres a lot copied from the shader graph code while some of it may not be neccessary.
    I mean, if you create Ports via myNode.InstantiatePort() you don't have to deal with the connections of edges on your own, but if you do so, you cannot draw a seach window if you drop an edge on the grid - why?

    Making the edges yourself is ...

    Code (CSharp):
    1. var edgeView = new Edge
    2. {
    3.     userData = serializedEdge,
    4.     output = sourceAnchor,
    5.     input = targetAnchor
    6. };
    7. edgeView.output.Connect(edgeView);
    8. edgeView.input.Connect(edgeView);
    9. _graphView.AddElement(edgeView);
    10. targetNodeView.UpdatePortInputVisibilities();
    11. sourceNodeView.UpdatePortInputVisibilities();
    12.  
    Hmm, I mean what does that mean? connecting the edgeView to itself? It works but the way it has to be written is quite confusing.
    Also the port thing ... For a behaviour tree for example, ports are not needed, you only need to know which nodes are connected and whats their position..
    The whole Edge-Connector thing who opens the search window is complicated.
     
    Last edited: May 10, 2020
  11. John_Leorid

    John_Leorid

    Joined:
    Nov 5, 2012
    Posts:
    646
    Actually with a bit of reflection you don't have to deal with all this stuff:


    Code (CSharp):
    1. Port GeneratePort(GraphNode node, Direction direction,
    2.             Port.Capacity capacity = Port.Capacity.Single)
    3.         {
    4.             Port newPort = node.InstantiatePort(Orientation.Vertical, direction, capacity, typeof(bool));
    5.  
    6.             //get the type of the class
    7.             System.Type type = newPort.GetType();
    8.             BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic;
    9.  
    10.             // get the field info
    11.             FieldInfo fieldInfo = type.GetField("m_EdgeConnector", bindingFlags);
    12.  
    13.             // set the value
    14.             fieldInfo.SetValue(newPort, new EdgeConnector<Edge>(edgeConnectorListener));
    15.  
    16.             newPort.AddManipulator(newPort.edgeConnector);
    17.  
    18.             return newPort;
    19.         }
    This code is inside MyGraphView.cs ( -->
    MyGraphView : GraphView
    ) but could be located anywhere.
    GraphNode is my custom node class (-->
    GraphNode : Node
    ).
    typeof(bool)
    is just there to provide any Type, because I don't need them for my Behaviour Trees.