Download

UMG thinks it's the wrong resolution?

Hello,
I’m moving an object in UMG in screen space, however it’s moving to the incorrect location.

Below you can see the window is 1280x720, and the object is set to be at 1269x685.
HOWEVER: it’s only at about 65% of the screen, which is where it would be if the resolution was at 1920x1080.

**GEngine->GameViewport->GetViewportSize() **reports 1270x686, and GSystemResolution reports the resolution to be at 1280x720.

So why is the position acting as if it’s 1920x1080? Is this an unreal bug or something I’m doing wrong? (The dot is anchored to top left in the root canvas panel)

Edit: **GEngine->GetGameUserSettings()->GetScreenResolution() **returns the proper size of 1920x1080. The proper math can get it looking right, but everything hits the fan once the screen is resized in any way.

TL;DR I just want that dot to be under the mouse, but getting the mouse position (1280,720) and putting the dot there puts it at the wrong spot, cus unreal thinks the screen size is 1920x1080. How do I solve this?

Hey, meant to reply to this earlier but forgot. AFAIK … if you are translating “UMG Pixels” << >> “Monitor Pixels” you have to either scale for DPI or unscale for DPI.

Example from code - switch where an icon is drawn either at current mouse position or center of screen.



/**
* Get DPI scale of UMG HUD.
* Used to translate actual pixels to DPI scaled pixels.
*/
float UPrimaryHUDWidget::Get_UMG_DPI_Scale()
{
 // need a variable here to pass to the GetViewportSize function
 FIntPoint viewportSize = GetWorld()->GetGameViewport()->Viewport->GetSizeXY();

 // we need to floor the float values of the viewport size so we can pass those into the GetDPIScaleBasedOnSize function
 int32 X = FGenericPlatformMath::FloorToInt(viewportSize.X);
 int32 Y = FGenericPlatformMath::FloorToInt(viewportSize.Y);

 // the GetDPIScaleBasedOnSize function takes an FIntPoint, so we construct one out of the floored floats of the viewport
 return GetDefault<UUserInterfaceSettings>(UUserInterfaceSettings::StaticClass())->GetDPIScaleBasedOnSize(FIntPoint(X, Y));
}

/**
* Get inverse DPI scale of UMG HUD.
* Use to translate DPI scaled pixels to actual pixels.
*/
float UPrimaryHUDWidget::Get_Inverse_UMG_DPI_Scale()
{
 float dpiScale = Get_UMG_DPI_Scale();
 if (dpiScale <= 0.0)
 {
  return 1.0f;
 }
 else
 {
  return 1.0f / dpiScale;
 }
}



// EXAMPLE USE - DRAW SOMETHING AT EITHER MOUSE LOCATION OR CENTER OF SCREEN

   // get position to draw the tool icon
   // if player is interacting or paused then draw icon at the mouse position
   // else player is walking so draw icon at the screen center
   FVector2D iconDrawPosition;
   if (stateType == PlayerStateType::INTERACTING || stateType == PlayerStateType::PAUSED)
   {
    UWidgetLayoutLibrary::GetMousePositionScaledByDPI(_playerController, iconDrawPosition.X, iconDrawPosition.Y);
   }
   else
   {
    // to get center of screen here we need to invert UMG DPI scaling
    FIntPoint size = GetWorld()->GetGameViewport()->Viewport->GetSizeXY();
    iconDrawPosition.X = (float)(size.X) * 0.5f *  Get_Inverse_UMG_DPI_Scale();
    iconDrawPosition.Y = (float)(size.Y) * 0.5f *  Get_Inverse_UMG_DPI_Scale();
   }



This was the magic line:


    
UWidgetLayoutLibrary::GetMousePositionScaledByDPI(Controller, mousePos.X, mousePos.Y);


Works perfecly, thankyou!