Search Unity

[SOLVED] Drawing a curve onto an Element

Discussion in 'UIElements' started by eidetic, Jun 9, 2019.

  1. eidetic

    eidetic

    Joined:
    Jun 27, 2016
    Posts:
    9
    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:
    9
    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
  3. antoine-unity

    antoine-unity

    Unity Technologies

    Joined:
    Sep 10, 2015
    Posts:
    58
    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 :)
     
  4. cecarlsen

    cecarlsen

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

    eidetic

    Joined:
    Jun 27, 2016
    Posts:
    9
    @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...
     
    cecarlsen likes this.
  6. cecarlsen

    cecarlsen

    Joined:
    Jun 30, 2006
    Posts:
    490
    eidetic likes this.