Creating a stretching arrow widget that rotates towards mouse position

I’m trying to create a custom arrow widget that rotates towards (and stretches towards) the target (in this case the hidden mouse cursor which has a spherical widget representing it here) but I’m having some issues with the widgets being offset to the right and stretching way too much.

UnrealTest2

Here is a gif with the issues (the purple “arrow” on the right side).

The white sphere is another widget which I’m using as a cursor and the red arrow is just a Arrow component in my Pawn blueprint which I set the rotation of using this node setup. It’s just for testing.

Here is my purple arrow widget setup:

  1. The widget (WBP_Arrow) just consists of two image (ArrowHead/ArrowLine) components on a canvas panel. I set their Position x/y so their midpoints would be at the anchor. I’m not sure if that’s correct. Screenshot:

  2. In my PlayerController I create the widgets (for the cursor and the arrow), create a reference variable and add them to the viewport like this.

  3. For the mouse cursor (the white sphere) I’m using the following node setup which I don’t have any problems with. Note that on the screenshot I have “RemoveDPIScale” checked, which does cause issues and offsets the widget, however when it’s unchecked it works pretty much perfectly. (example here of the offset with the checkbox enabled)

  4. In the following steps I’m guessing is probably where my problems start. This is also in my PlayerController, I get the Controlled Pawns Position, project world to screen and feed that into a custom event (UpdateArrow) from the WBP_Arrow widget as “GunPos x/y” then get mouse position and feed it as well into the same custom event inputs as “MousePos x/y”:

  5. Inside the WBP_Arrow widget I then use the following node setup to get a delta, length and degrees of rotation and apply it to the ArrowHead/ArrowLine images with a “Set Render Transform”:


    Edit: Full resolution screenshot here.

I suspect I’m doing something very wrong here: In the above linked screenshot from within the WBP_Arrow widget, to get the delta I’m subtracting the Vector2d GunPos from the previous step with the Vector2D MousePos.

To get the length I plug the Delta variable into Vector2dLength node and create a float variable called Length. Then I plug that into the “In Transform Scale Y” input of the “Set Render Transform” for the arrow line

To get the required angle of rotations needed I take the X/Y from the delta, plug it into a “Atan2(Radians) node”, plug it into a “Radians to degrees node”, subtract -90 (not sure why I had to do that but the rotations were off otherwise) and set that as a “Rotation Degrees” variable. Which I then plug into the “Set Transform Angle” input of the “Set Render Transform” for both the Arrow head and the Arrow line.

I then just take the GunPos vector2d (for the Arrow line) and MousePos vector2d (for the Arrow head), straight from the custom events inputs to the “In Transform Translation” in the “Set Render Transform” nodes.

As the cursor was also offset when the “Remove DPIScale” is checked (as mentioned in step 3 above), I suspect I’m probably missing something similar for the arrow. And probably some other things.. any tips here would be greatly appreciated.

Slight update with solutions to everything in case anyone wonders similar things in the future:

Step 1: Split the arrow widget into two separate widgets (WBP_ArrowLine & WBP_ArrowHead instead of a single widget)

Step 2: make slight adjustments to image component position and pivots:


Above is the WBP_ArrowHead, the position for the image component is x: -50 y:-50 (as the image size is 100)
the pivot is x:0.5, y:0.5


Above is WBP_ArrowLine image component is set to position x:-50 y:0 with pivots x:0.5, y:0.0

Step 2:


Easy, just spawn the widgets and add to viewport in PlayerController

Step 3:

Now as I couldn’t just click a checkbox to disable “RemoveDPIscale” as was possible to do in the SetPositionInViewport node I used for the cursor (mentioned in the first post), I needed to divide the mouse and gun positions with “get viewport scale” nodes before feeding it into the CustomEvents of the arrow widgets. This is also in the PlayerController

Step 4:


In the Wbp_ArrowHead widget event graph, no changes needed to be made (aside from removing the logic related to changing the arrow line as the line is no longer a part of the same widget)

Step 5:


Some changes were made here in WBP_ArrowLine, first remove the “Set Render Transform” related to the arrow head as this only affects the arrow line.

Secondly: Divide the length by 100 before feeding it into the “in transform scale Y” makes the line now the correct length between the gun and the mouse.

Thirdly: Multiply the delta X and Y with -1 before it goes into the Atan2Radians node so that the line will rotate the correct way

Now everything works good enough:
UnrealTest3

I really doubt I did this efficiently.. seems like a messy way having to split up the arrow into two separate widgets but there was always some kind of offset when I tried keeping them together sadly. At least it works for now.

1 Like