Ran into this as well due to having UI objects in both HUD (not DPI scaled) and HUDWidget (DPI scaled). Use these to translate when needed:
#include "Runtime/UMG/Public/Blueprint/WidgetLayoutLibrary.h"
#include "Runtime/Engine/Classes/Engine/UserInterfaceSettings.h"
#include "Runtime/Engine/Public/SceneView.h"
/**
* 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
// the fuction returns a float, so we can return the value out of our function here
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;
}
}
An easy test to ensure your DPI scaling works is draw a crosshair in the center of the DPI-scaled HUD based on the actual ViewPort pixel width and height:
// to get center of screen here we need to invert UMG DPI scaling
FVector2D iconDrawPosition;
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();
thanks for the answer. In fact the joystick is a bit particular.
If you want to apply the DPI as any other, you need to return 1.f in GetScaleFactor(). Otherwise, you apply twice the DPI scale.
I opened a issue case in Unreal and hope they will fix that soon. Otherwise, you need to setup your own class and override a lot of stuff to get this little change working.