I think all the answers here are incomplete as they assume the following:
- user has all monitors with the same resolution
- monitors are aligned from left to right
- runs only on windows (on linux apparently it does not work properly only in windowed mode)
- destination monitor also has a native resolution larger or equal to the game resolution
The only information you need is from FMonitorInfo.WorkArea Left/Top.
FDisplayMetrics Display;
FDisplayMetrics::GetDisplayMetrics(Display);
// Start on the main display by default
int32 MonitorNumber = 0;
FParse::Value(FCommandLine::Get(), TEXT("monitor="), MonitorNumber);
// Get the correct monitor index
int32 MonitorIndex = INDEX_NONE;
if (MonitorNumber == 0)
{
// Start monitor on the main screen
for (int32 Index = 0; Index < DisplayMetrics.MonitorInfo.Num(); Index++)
{
if (DisplayMetrics.MonitorInfo[Index].bIsPrimary)
{
MonitorIndex = Index;
break;
}
}
}
else
{
// Normalize
MonitorIndex = MonitorNumber - 1;
}
if (DisplayMetrics.MonitorInfo.IsValidIndex(MonitorIndex))
{
const FMonitorInfo Monitor = DisplayMetrics.MonitorInfo[MonitorIndex];
// check if UserSettings.ResolutionSizeX > Monitor.NativeWidth || UserSettings.ResolutionSizeY > Monitor.NativeHeight
// if true then change your game resolution to Monitor.NativeWidth, Monitor.NativeHeight
const int32 WindowPosX = Monitor.WorkArea.Left;
const int32 WindowPosY = Monitor.WorkArea.Top;
const FVector2D Position(static_cast<float>(WindowPosX), static_cast<float>(WindowPosY));
if (GEngine && GEngine->GameViewport)
{
TSharedPtr<SWindow> Window = GEngine->GameViewport->GetWindow();
// Hack for linux
#if PLATFORM_LINUX
const EWindowMode::Type CurrentWindowMode = Window->GetWindowMode();
Window->SetWindowMode(EWindowMode::Windowed);
#endif
Window->MoveWindowTo(Position);
#if PLATFORM_LINUX
// Set back to original
Window->SetWindowMode(CurrentWindowMode);
#endif
}
}