[SOLVED] Drawing a curve onto an Element

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:

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

  1. 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!

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:

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:

.my-class {
      pointer-events: none;
}

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.

1 Like

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 :slight_smile:

1 Like

@eidetic did you manage to draw curves without the IMGUI Handles class, within a UIElement?

@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…

2 Likes

Apparently UIElements has a class named ImmediateModeElement that allows you to draw things directly.

1 Like

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).

2 Likes

I can’t find generateVisualContent mentioned anywhere else than in the scripting API. Could you perhaps provide a simple example?

Sure,

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

4683491–441413–GenVisuals.cs (2.02 KB)
4683491--441416--unitylogo_small.png

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.

This is excellent, especially if the API will be exposed at runtime.

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?

Hello,

The expected order of triangle indices has changed in the latest 2019.3 builds.

Please see this thread Draw a line from A to B - Unity Engine - Unity Discussions

I see! Thank you, that solved it.

A year has passed. Any updates on this?

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?

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*

2 Likes