Search Unity

[SOLVED] Drawing a curve onto an Element

Discussion in 'UI Toolkit' started by eidetic, Jun 9, 2019.

  1. eidetic

    eidetic

    Joined:
    Jun 27, 2016
    Posts:
    14
    Hi all,

    I'm creating an interface using UIElements and need to draw curves representing connection points that run over the top of some Elements.

    This used to be easy using the Handles API:
    Code (CSharp):
    1. Handles.DrawBezier(startPoint, endPoint, startTangent, endTangent, color, null, 5);
    I have attempted to insert an absolutely positioned IMGUIContainer into the element, and place this on top of everything in order to draw the beziers using the same Handles code, but the IMGUIContainer doesn't allow click events to pass through onto any regular UIElements placed underneath it.

    Perhaps this image will help make more sense... Once I draw this red curve in an IMGUIContainer on top of other Elements, it blocks all Elements underneath the whole rect of the curve from detecting any mouse events:



    I have had a look at the UnityCsReference repo on Github to see how the Unity team are drawing the connection lines for their own GraphViewEditor, but I find it pretty hard to follow and I think it looks like they are using something called "MeshGenerationContext" to draw the lines, which is an experimental API and is not yet documented. I've also had a poke around the VFX graph repo but likewise can't make sense of it.

    Does anyone know of either:

    1) A way to bypass any mouse events of an IMGUIContainer so that clicks can be registered for any Elements placed underneath the overlapping container. Obviously this would be a temporary solution because eventually I don't want to use IMGUI at all.

    or

    2) A way to draw arbitrary curves inside UIElements without the use of IMGUI and without losing click events of Elements placed underneath these curves. Perhaps someone can explain the MeshGenerationContext? Or maybe there is another alternative?


    Thanks a lot!
     
    Last edited: Jun 10, 2019
  2. eidetic

    eidetic

    Joined:
    Jun 27, 2016
    Posts:
    14
    For anyone interested I've found the solution...

    If you do not want a VisualElement to respond to mouse events, you can set the Element's "pickingMode" to Ignore:
    Code (CSharp):
    1. myVisualElement.pickingMode = PickingMode.Ignore;
    This is handy, but if there is anyone from the UIElements team reading this, maybe a request would be to also be able to set this in the StyleSheet like how it's handled in web development.

    In CSS, you can set the "pointer-events" property to change how mouse behaviour is handled on the element like so:

    Code (CSharp):
    1. .my-class {
    2.       pointer-events: none;
    3. }
    Obviously it doesn't really matter as it works this way... just thought the vernacular could be standardised.

    Anyway, my hat's off to the UIElements team... you've done a great job so far.
     
    Last edited: Jun 10, 2019
    SudoCat likes this.
  3. antoine-unity

    antoine-unity

    Unity Technologies

    Joined:
    Sep 10, 2015
    Posts:
    780
    Hello,

    I think the reasoning for us was to include all functionality-oriented properties on VisualElement (and thus UXML for example
    picking-mode="ignore"
    ) directly rather than its styles.

    However for more CSS compatibility it's a good idea to control this via USS. We'll keep it in mind.

    And thanks for the kind words :)
     
    SudoCat likes this.
  4. cecarlsen

    cecarlsen

    Joined:
    Jun 30, 2006
    Posts:
    864
    @matt42hughes did you manage to draw curves without the IMGUI Handles class, within a UIElement?
     
  5. eidetic

    eidetic

    Joined:
    Jun 27, 2016
    Posts:
    14
    @cecarlsen Unfortunately not.

    I don't know if UIElements has a way to draw arbitrary shapes/gizmos/lines yet...

    I'm hoping for SVG support...
     
    SudoCat and cecarlsen like this.
  6. cecarlsen

    cecarlsen

    Joined:
    Jun 30, 2006
    Posts:
    864
    eidetic likes this.
  7. antoine-unity

    antoine-unity

    Unity Technologies

    Joined:
    Sep 10, 2015
    Posts:
    780
    Hello,
    We are definitely on this path. ImmediateModeElement is a stopgap solution for custom shapes but in 2019.3 we started exposing more low level rendering primitive which do not require using retained mode at all.

    Since this is brand new the manual section is not available yet but
    VisualElement.generateVisualContent
    is available for exactly this purpose (see Scripting API). It only provides basic triangles with colors and textures but more will come in the future.

    SVG support is also in the works (slated for 2019.3).
     
    SudoCat and cecarlsen like this.
  8. cecarlsen

    cecarlsen

    Joined:
    Jun 30, 2006
    Posts:
    864
    I can't find generateVisualContent mentioned anywhere else than in the scripting API. Could you perhaps provide a simple example?
     
  9. antoine-unity

    antoine-unity

    Unity Technologies

    Joined:
    Sep 10, 2015
    Posts:
    780
    Sure,

    I just grabbed something we've done internally for basic testing, more examples to come.
     

    Attached Files:

  10. cecarlsen

    cecarlsen

    Joined:
    Jun 30, 2006
    Posts:
    864
    Thank you, this helps. Looking forward to try this out.

    Any reason why you decided to invent a new syntax for setting indices and vertices? Why not mimic how Canvas works (OnPopulateMesh, VertexHelper, AddVert, AddTriangle)? It's getting quite confusing with three different mesh interfaces; Mesh, Canvas VertexHelper and now UIElements MeshGenerationContext.
     
  11. recursive

    recursive

    Joined:
    Jul 12, 2012
    Posts:
    669
    This is excellent, especially if the API will be exposed at runtime.
     
  12. skatebee

    skatebee

    Joined:
    Jan 6, 2020
    Posts:
    4
    Just tried using this code in the latest release beta (2019.3.05f) and it doesn't render the mesh. However, the same code in an earlier version (2019.3.0a10) works as expected. Has anything in the API changed that might change the way to use these methods?
     
  13. antoine-unity

    antoine-unity

    Unity Technologies

    Joined:
    Sep 10, 2015
    Posts:
    780
  14. skatebee

    skatebee

    Joined:
    Jan 6, 2020
    Posts:
    4
    I see! Thank you, that solved it.
     
  15. Nexer8

    Nexer8

    Joined:
    Dec 10, 2017
    Posts:
    271
    A year has passed. Any updates on this?
     
  16. Aspekt1024

    Aspekt1024

    Joined:
    Sep 29, 2016
    Posts:
    12
    Also keen to know if there's been any updates on this. I'm currently drawing lines by creating triangles and my next step is curves. I can't see of a way to do this yet outside of IMGUIContainer.

    It's possible I've missed something through google searches, or otherwise is there something in the pipeline?
     
  17. Kirsche

    Kirsche

    Joined:
    Apr 14, 2015
    Posts:
    121
    You need to install their GraphTools Foundation package as described here: https://docs.unity3d.com/Packages/com.unity.graphtools.foundation@0.9/manual/index.html

    Then you can take a look at the following class that shows how to do it:

    com.unity.graphtools.foundation@0.10.1-preview\Editor\Overdrive\GraphElements\Elements\UIElements\EdgeControl.cs
     
    Aspekt1024 and Nexer8 like this.