Use mouse draw line in the 2D,how to do?

How can i draw 2d line on umg widget?

[video][/video]

Once you have 2d coordinates of the points the lines are supposed to connect, you can override onPaint in the widget.

in teh HUD,how to set

Here’s my take on it, see if it helps:

I created an array to store the coordinates of where in the widget the mouse clicks: Points

I’ve overridden OnMouseButtonDown and add a 2d coordinate to the aforementioned Points array whenever the user clicks with the *LeftMouseButton *only.

And here’s the OnPaint:

DrawLines handles all the lines for the generated points and an additional DrawLine draws a line from the last element of the Points array to the mouse position on the screen.

If you want to detect clicks on the entire canvas, set its Visibility to Visible. Here I’ve placed a border which is the only Visible element so the clicks outside do not register.

1e84ff35d2cb91575d1b9b052b87e7c2.gif

This is by no means perfect by should get you started, good luck!

2 Likes

Very Thank! OnMouseButtonUp,stop draw line,save Already draw line,how to do!

The easiest way would be to store the Points arrays in another Array.

You probably do not want to use *OnMouseButtonUp *here - it will interrupt your drawing every time you click. Perhaps you could add a check for the RightMouseButton in the OnMouseButtonDown. Every time the user pressed RMB, add Points array to another array - the OnPaint can draw the whole thing in a loop.

It might be only me but the service you use for hosting those video asks me to install additional software and it’s not in English so I can either not watch it or risk installing something dodgy. It works on my phone, though. If you make these examples easier to access, chances are you’ll attract more attention.

The solution with the nested array I posted above should work fine for drawing multiple lines. I saw you post multiple questions, I’ll just answer some of them here:

  • To loop through an array of lines containing points:

looplines.PNG

[HR][/HR]

  • To display text, you’ll need to create widgets, something very simple will do:

widget.PNG

Set the text_label’s *isVariable *to True (upper-right corner of the details panel) so you can access it later and set its text (distance)
text_label is centred horizontally and vertically, the rest is on default

[HR][/HR]

  • To add distance labels, create a widget every time the user clicks:

The widgets that have already been placed are stored in the DistWidgets array
The widget that is still being dragged around has its own variable DistWidget, and is added to the DistWidgets array as soon as the point has been placed; a new widget is created for the next line fragment

[HR][/HR]

  • To find coordinates, you’ll need a bit of math:

Position between two Points is (A+B)/2
Distance is length of (A-B)
Those two values are sent to the Widget

[HR][/HR]

  • To make a straight line, constrain either X or Y of the mouse input

[HR][/HR]
313578ddad5571564720631d69dc7609.gif

2 Likes

line Separate,how to do!
2212.PNG

any idea for line separate?or size for draw line?

I think that HUD’s class allows for tinkering with line’s size.

How to paint separate line - can’t remember this setup well but I’d create an array of points arrays. Add new elements once you’ve finished with your line.

As in, contain a set of points which makes a line within an outer array that contains the lines. Rinse & repeat.

Everynone, in the blueprint where you show how to loop through the array of lines, which blueprint would this go in? The on mouse button override or the onPaint override? Thanks if you can help out, I know this thread is very old :slight_smile:

Blast from the past, eh?!

It’d have to be in the widget’s *onPaint *since you need to provide the Context data.

okay that makes sense, thanks so much for answering! And one more quick question that you might know how to approach, i want to use the drawing in a notebook/journal widget that the player can open and it has multiple pages. Would there be a way to only have the drawings show when youre on a certain page in the notebook. I was trying to mess with the visibility but i’m not sure where to do it

There sure is a way. The approach would depend on how you structured the journal.

For the most basic of setups, you could have an int variable indicating which page the drawing is on (Page with Drawing). A *Branch *in the *onPaint *checks whether we’re on page 3 or not (Current Page We are On). Something along the lines (ehm) of:
[HR][/HR]
If there is more than 1 page with a drawing, one could create a dictionary map that holds [page number | array of lines]. As in:

You can write to this map and store it easily in a save game. And the struct the map holds (here, sLines) can store more stuff - like EVERYTHING that’s on that page, for example :slight_smile: [HR][/HR]
If the journal is a more complex beast, perhaps the pages should be separate widgets that live inside a widget switcher (so when the player flips through them, you do not need to recreate every page from scratch every time). In a case like this, you could check if the array of point the page stores is larger than zero.

Essentially, every page widget can be painted on (which can also be a controlled with variable the page holds) but only shows the lines if there are any to show. [HR][/HR]
For even more advanced stuff there are lists- for when you must have a *Skyrim *number of fancy books with dozens of pages each but do worry about performance / memory footprint.

Do tell if this makes sense.

Yes that worked! It only allows me to draw while on the certain page i selected, but it lets me draw all over the screen rather than just inside the journal page(which only takes up a portion of the screen) how can i restrict this like you have above in the little window? and then also, to clear any drawings, I would just empty my array right?

I am also having some trouble figuring out how to stop drawing once i start. Any suggestions?

Above, that’s the bit that draws the line between the last point and the cursor. I’d gate it with a Branch controlled with a boolean set onMouseDown. When the left click goes down, set bool to True; when right clicks goes down, set it to false. That *should *do it.

Pretty much.

It looks just like a fake border to me ;p, just to demo things in context. The answer to this depends on how it’s supposed to work from the gameplay point of view. As in, what should happen when we exceed the allowed area? Do we draw part of the line, stop drawing this line, stop drawing altogether, draw a line at the edge, some other criteria…

There’s several things one could do.

  • constrain the cursor movement to widget area (may feel horrible to the player, can’t recommend it)
  • have onPaint respect coords calculated during onMouseMove by translating absolute screenspace to local widget geometry, yada, yada, yada; 2d vector math. Essentially, compare screensize to widget size and check if the mouse coords are within range. Have the check put up a flag that can be used elsewhere in the code.
  • or it might be enough to play dumb and do this:

We only get to paint if the mouse is over the widget; the bool controls the condition:

You will need to perform the same check when the mouse goes down and a coord is added (or not) to the array.
[HR][/HR]
Not sure how you’ve set it up so far but I’d probably start the whole thing by creating a user widget one can draw on and make it a part of the page. This way you can include it (even add it dynamically) to pages that need it and no longer need to worry about exceeding boundaries. This way you could read mouse position from the widget, rather than from the controller - which is not that sensible here to start with… :expressionless:

Here’s a slightly more sensible approach to something like this:

zipped project:

vid: https://i.gyazo.com/c4d1e1d049689c73159f65c8717ac8c6.mp4

Leaving the area or right clicking stops drawing. Drawing of multiple separate lines is not included, here you continue drawing where you stopped last.

Thank you so much, this has been so helpful so far. I am quite new to Unreal development and I would love to know exactly how to make separate lines with this project. I have tried for a while now to make an array of arrays and such but it’s just not working in my favor. Sorry to dig up this post again