Download

UMG - Mouse screen position problem

Hi everyone,

I’m trying to move a item with the mouse by using the “Set position” option in BP. It is working but there seems to be some discrepancy between the mouse position and the dragged texture position.

This is my dragged-image set up in the widget “On mouse move” event:

setimageposition.png

And this is the actual problem: When the mouse is near the top left of the screen, the item is shown very close to the mouse position, but when the mouse is near the bottom right of the screen, there is an extremely large distance between both:

Top left (good):

275024c3caaa93eb7d0cb54b6fbccf24f098e8b6.png

Bottom right (bad):

wrongscreenposition.png

I posted a question in the answerhub but there doesn’t seem to be any answers yet so I thought I’d try it in the forum.

Any ideas on how to solve this? Thanks a lot!

Hello,
do you have the same issue in windows viewport / new editor and full screen mode. If there is a difference it may be that the x/y values return are relative to current window for mouse and relative to screen for your item (or the opposite).

Thanks for asking! Indeed:

  1. In editor window, it appears as shown above (wrong).
  2. In standalone game (fullscreen), it appears as shown above (wrong).
  3. In editor fullscreen, it works perfectly.

The fact that it works correctly in editor fullscreen but incorrectly in standalone fullscreen game is puzzling…

Good news : games are usually in full screen ^^ I would try to see how is set the mouse position on hud start and apply the same modification to the item.

I ran into this same issue when making my inventory system. If you run a print screen of the mouse coords while you are dragging your item around, you will see that it gets your desktop’s resolution, rather than just the viewport’s. I had also asked on the answerhub a couple weeks ago but never got an answer.

Are you trying to write the drag and drop between inventory slots function right now or something else? I can probably help if I have a better understanding of what exactly you are trying to do.

-Haka

Hey David, thanks for stepping in!

Indeed, this is for dragging items between slots. The mechanism works fine, but I can’t find a workaround for this yet.

Resolution seems to be the key – If I play standalone game using my desktop resolution in the advanced settings, there is no apparent difference between the cursor and item position. But how to set this up dynamically?

Hey Lucas,

I’m just going to post screens of my current drag and drop. My whole system is UMG and iirc you are using kind of a hybrid but hopefully this helps you. Feel free to ask any questions you want. Btw my screenshots will cut off some nodes but it’s only nodes that I’m still experimenting with.

I have a custom widget setup that is an image inside a button, I call this my inventory item (though I use it for equipment and hotbars now as well). This is the widget that is created inside the uniform grid when inventory is created.

I bound the below screen on the (OnMouseButtonDown)
ImagePush.PNG

On Drag Detected
Drag Detected.PNG

On drag over is not used currently

On Drop part 1
4052f3b2453c2cb50329cf2fb8a22e59735175a6.png

On drop part 2
a1343b7282aafefc3d221020a46c3c06f2b8069a.png

I had also tried using mouse position but could not for the life of me find a way to make it work so I went all UMG. I may be missing parts but I can’t find anything yet. Please let me know if this helps in any way.

-David

PS: on the drop part I have a function called “Prevent double drop”. This is kind of a weird one but it shouldn’t affect you since you have a button to drop the item you’re selecting. For reference though, if you say wanted to drag the item to “open space” on the screen to have it drop, you’d need to call a “on drop” function on the main screen to do this. While that works without issue when you go back to trying to move items and you drop an item on your inventory slot, because its above the main screen, the on drop gets called on both widgets. Thankfully it calls one before the other so I was able to hack around it to make it only drop to one or the other.

Thanks a lot David — I’ll have a look!

bdfbca1ea779640d055da53ac66df7f5993ed6ff.png

here is something that may or may not be useful.

If you’re taking raw mouse screen space coordinates and you want to move a nested widget into a particular position. Don’t forget about the DPI Scaling that affects the UI. You’ll need to do what the viewport does when you set the position of a widget at the viewport level (SetPositionInViewport of a user widget).

// Pseudo Code
float Scale = GetViewportScale();
FVector2D WidgetPosition = MousePosition / Scale;

I’ve thought about adding a utility function for this, if anyone wants to throw it into a utility library here’s what I’ve got planned for 4.7.

UFUNCTION(BlueprintPure, BlueprintCosmetic, Category=“Viewport”)
static bool GetMousePositionScaledByDPI(APlayerController* Player, float& LocationX, float& LocationY);

bool UWidgetLayoutLibrary::GetMousePositionScaledByDPI(APlayerController* Player, float& LocationX, float& LocationY)
{
if ( Player && Player->GetMousePosition(LocationX, LocationY) )
{
float Scale = UWidgetLayoutLibrary::GetViewportScale(Player);
LocationX = LocationX / Scale;
LocationY = LocationY / Scale;

	return true;
}

return false;

}

Nick, you’re amazing. This is perfect! Works like a charm :slight_smile:

This is the BP set up in case anyone else needs it:

55e644edf2d05fd75dce2d3b25dc5d6063596e35.png

Hi,

I’m having a hard time making this work using Mouse Event data. When using the GetScreenSpacePosition function, it works properly in full screen (1680x1050), but when I launch in PIE, there is an offset since it’s returning the mouse location based on the desktop resolution. Does someone know how to convert the mouse position into viewport coordinates or point me to what I am doing wrong? The widget I am moving is a simple widget containing a border and an image and no Canvas Panel (so there’s no anchor).

This is the widget blueprint that manages the movement of the DragIconWidget instance:

The result in New Editor Window or Stand Alone Game (Working as expected):

The result when playing in PIE (with the offset)

I have tried implementing what Chooka was suggesting, but if I do so, I get negative mouse position values and it doesn’t work in full screen or PIE:

Thanks,

Try using Player -> Get Mouse Position instead of Mouse Event -> Get Screen Space Position.

It should match the current viewport.

Hi Kris,

I have tried that previously, but the function works only for one frame and then returns false, so I am only able to get the initial position of the mouse and it doesn’t update after that. I’m sure if I tick the function outside the OnMouseMove, then it will work, but I would like to update the position inside the OnMouseMove function, hence why I was using the MouseEvent data structure which contains the updated coordinates.

Hmm, annoying.

Oh well… this is what I’ve been using.
I didn’t mention it earlier because its requires a bit of C++ work.
I’ll have to get Rama to add it to his collection:



    UFUNCTION(Category = "Interface", BlueprintPure)
    static void BreakGeometry(const FGeometry& InGeometry, FVector2D& OutPosition, FVector2D& OutAbsolutePosition, FVector2D& OutSize, float& OutScale);

void UGBUIFunctionLibrary::BreakGeometry(const FGeometry& InGeometry, FVector2D& OutPosition, FVector2D& OutAbsolutePosition, FVector2D& OutSize, float& OutScale)
{
    OutPosition = InGeometry.Position;
    OutAbsolutePosition = InGeometry.AbsolutePosition;
    OutSize = InGeometry.Size;
    OutScale = InGeometry.Scale;
}

AbsolutionPosition should match the offset you speak of.
See https://answers.unrealengine.com/storage/temp/24566-desiredwidgetsize04.jpg .

Thanks for the answer Kris.

I managed to get it work using other methods, but I finally decided to simply use the DragDropOperation, it really simplifies everything since there is a lot less overhead. Also, it works well in PIE and else.

Well this is possible without one line of c++ if you have a widget with a fullscreen canvas you an expert the geometry from that and implement a function wich uses that main geometry as well as the mouse event from the child widget and get to the result

I found the solution: Close the Engine. Right click on the EpicGamesLauncher > Properties > Compatibility. Check the box for “Override high DPI scaling behavior.” Set “Scaling performed by:” to “System”. This works for me across resolutions/ windows scaling.

[ATTACH=JSON]{“data-align”:“none”,“data-size”:“full”,“data-tempid”:“temp_142961_1532250445893_865”}[/ATTACH]
This solution works for any resolution.
Don’t forget to uncheck “Remove DPIScale”.

the solution is? get the graph: get mouse position scaled by DPI