Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How to get game build to run on Main Display

Discussion in 'Windows' started by bbjones, Apr 26, 2022.

  1. bbjones

    bbjones

    Joined:
    Feb 1, 2016
    Posts:
    85
    Technically things seem to work correctly I suppose, canvas/cameras are targeting Display 1, but on my computer that is not my Main Display in Windows, display 2 is.

    Every other game on the planet opens on my Main Display, and all builds I've ever made in Unity also opened on my Main Display until I upgraded to Unity v2021.

    Now all builds open on my secondary monitor, which is not my Main Display, but does show as Display 1 in Windows display settings.

    I can change this via shortcuts and can include video settings for players to change it, but is there anyway to have the build work like it did before, or tell unity builds to open on the Main Display regardless of what the display number is?
     
    trombonaut likes this.
  2. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,646
  3. bbjones

    bbjones

    Joined:
    Feb 1, 2016
    Posts:
    85
    Today I installed Unity v2021.3.1f1 LTS (cause I wanted to get my project into LTS) and upgraded my older v2020.x LTS project, tested a build once I got through all the upgrade issues and saw the wrong monitor problem.

    I have also created multiple builds of test projects with v2021.3.1f1 LTS and see the same problem.

    I have just done a new test, new empty project with no changes/other imports, made a Windows 64bit build of the default empty scene and same problem.

    Once I shift the EXE to another monitor (using WinKey+SHIFT+ArrowKey) the EXE will then open on the Main Display. Nothing I did in code of course, just Windows 10 doing its thing.
     
  4. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,646
    Would you be able to report this as a bug, and include what gets reported by https://docs.unity3d.com/ScriptReference/Screen.GetDisplayLayout.html on your machine in it? I suspected perhaps we are misinterpreting old saved preferences in upgraded projects, but if an empty project is affected too, we're probably misdetecting which display is the main display.
     
  5. bbjones

    bbjones

    Joined:
    Feb 1, 2016
    Posts:
    85
    Will do, but it does beg the question: How do you tell Unity to use the Main Display instead of whatever is on Display 1?

    What if I actually want my game to start on Display 1 even when it isn't the Main Display?

    I don't see any settings related to this (use Main Display), only the list of Displays for things like Canvas and Cameras.
     
  6. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,646
    Unity should by default make your game start on the main display when you run it the first time. Afterwards, it should open up on whatever display it was closed on.

    There is no project setting to change that behaviour because when you build a project from the editor, it has no idea what kind of setup the game will run on.

    However, there are ways to change it at runtime. There is a C# API to move the game to another display: https://docs.unity3d.com/ScriptReference/Screen.MoveMainWindowTo.html. We also have command line arguments ("-monitor 3") to make the game start up on the specified display.
     
  7. bbjones

    bbjones

    Joined:
    Feb 1, 2016
    Posts:
    85
    Side note, when making a new unity project, Unity itself opens on my Display 1, not my Main Display.

    What exactly did you want from GetDisplayLayout()?

    That just gives me a list of my displays in order from Display1, Display2 etc.
     
  8. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,646
    The order of the displays it gives you, and how that compares with Windows settings (including which display is set to main display). I suspect it will require us to do some digging in order to reproduce it.
     
  9. bbjones

    bbjones

    Joined:
    Feb 1, 2016
    Posts:
    85
    Well it's giving my displays back in the order Display1, Display2, which I suppose makes sense.

    But in my case, Display2 is my Main Display. Are you expecting the order should come back Display2, Display1?

    My log info output in order:

    Display1
    Name: W2340
    Height: 1080
    Width: 1920
    RefreshRate: 148351648/148351648
    WorkArea: (x:0, y:0, width:1920, height:1040)

    Display2 (Main Display)
    Name: B326HUL
    Height: 1440
    Width: 2560
    RefreshRate: 59951/59951
    WorkArea: (x:0, y:0, width:2560, height:1400)

    upload_2022-4-26_17-11-33.png
     
  10. bbjones

    bbjones

    Joined:
    Feb 1, 2016
    Posts:
    85
    Bug reported, ticket number: 1423262
    Case: 1180011
     
  11. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,646
    I'm not sure which order it should return displays in off the top of my head, but that information is going to be very useful when investigating the bug. Thanks for the report!

    By the way, when posting bug numbers in the future, only the number part (1423262) is needed. The unique string after that is your unique key that allows you to look at bug report details and that might include your personal info. I edited it out of your post for now, but keep that in mind for the future :).
     
    bbjones likes this.
  12. bbjones

    bbjones

    Joined:
    Feb 1, 2016
    Posts:
    85
  13. DoctorShinobi

    DoctorShinobi

    Joined:
    Oct 5, 2012
    Posts:
    219
    This bug affects my project too, and it's quite a critical issue in my case. Is there a workaround to this until it's fixed in the 2021 LTS?
     
    trombonaut likes this.
  14. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,646
    Not a good one, unfortunately. You could technically detect on startup if it's the first time you launch the game and you're not running on the main display, then move the window to it, but that would require using WinAPI directly.

    We are in the process of fixing & backporting it. It shouldn't take much longer.
     
    DoctorShinobi likes this.
  15. DoctorShinobi

    DoctorShinobi

    Joined:
    Oct 5, 2012
    Posts:
    219
    Hey @Tautvydas-Zilys, sorry for nagging, but do know if this issue is still being worked on?
    It's been set as "Fix In Review for 2022.2.X" for quite a while now, and I'm starting to fear it will be another couple of months before this fix is backported into the 2021 LTS.
     
    trombonaut likes this.
  16. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,646
    It's being actively worked on. The fix was ready but then failed an internal test suite so now is being redone. I can't give you an ETA for getting it done but we're trying our best to get it in asap.
     
    DoctorShinobi likes this.
  17. DoctorShinobi

    DoctorShinobi

    Joined:
    Oct 5, 2012
    Posts:
    219
    Thank you for letting me know it's being worked on. I can relax now that I know it's not in limbo.
     
  18. toddw

    toddw

    Joined:
    May 9, 2010
    Posts:
    129
    Just recently migrated from a 2020 build up to 2021.3.4f1 and had this problem as well. Thanks to this sample https://programtalk.com/vs4/csharp/...owSample/Assets/Scripts/SettingsMenuScript.cs I fixed this using the following code on a script that runs on my splash screen Scene.

    Code (CSharp):
    1.    
    2.     void Awake()
    3.     {
    4. #if !UNITY_EDITOR
    5.         // fixes new Unity2021 bug where the secondary monitor was being chosen when the game launches in a release build
    6.         StartCoroutine("MoveToPrimaryDisplay");
    7. #endif
    8.     }
    9.  
    10.     IEnumerable MoveToPrimaryDisplay()
    11.     {
    12.         List<DisplayInfo> displays = new List<DisplayInfo>();
    13.         Screen.GetDisplayLayout(displays);
    14.         if (displays?.Count > 0)
    15.         {
    16.             var moveOperation = Screen.MoveMainWindowTo(displays[0], new Vector2Int(displays[0].width / 2, displays[0].height / 2));
    17.             yield return moveOperation;
    18.         }
    19.     }
     
    trombonaut, CitrioN and DoctorShinobi like this.
  19. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,646
    Hey, I've got some technical details to share.

    When Unity game starts up, it checks if it's the first launch by looking at presence of player prefs:

    1. If player prefs are found, then it uses settings from previous run. In other words, if previous run was on a secondary display, so will this one (and this is not a bug).
    2. If player prefs are not found, then we will use the display that Windows happens to spawn it on (we pass CW_USEDEFAULT constant so that Windows decides where to spawn it). This is where the bug seems to occur: for whatever reason, on your machines it gets spawned on non-primary display.

    This means that you can only reproduce the bug on the first run, or if you wipe player preferences (which can be found in Windows registry, for instance the path for a new project is "HKEY_CURRENT_USER\SOFTWARE\DefaultCompany\New Unity Project (211)"). We believe we figured out what causes this to happen, but just to make sure we fix the same thing, can you answer a few questions?

    1. Are you launching the game via Build & Run from Unity or are you launching it through Windows Explorer?
    2. When you launch the game, is Windows Explorer window by any chance not on the primary display?

    If you need to try these out, please nuke the registry keys before trying each scenario. Otherwise it'll just use the previous setting.
     
  20. DoctorShinobi

    DoctorShinobi

    Joined:
    Oct 5, 2012
    Posts:
    219
    I deleted the registry keys. Using Build & Run opens it on my main monitor. Opening directly from a Windows Explorer opens it on the screen that contains the window.

    I don't usually open my builds on the secondary monitor, so it's weird it was set as the select monitor when I ran it for the first time after upgrading to 2021.3
     
  21. OyvindE

    OyvindE

    Joined:
    Feb 1, 2018
    Posts:
    8
    I encountered this as well.
    Builds made with 2021.3.4f1 opens on second monitor, while builds made on 2021.1.19f1 opens on main monitor.
    If I change the 2021.3.4f1 build to open on main monitor (ALT+ENTER and move it to correct monitor), all builds made on 2021.1.19f1 will now open on second monitor instead, completely opposite of 2021.3.4f1.
     
    DoctorShinobi likes this.
  22. bbjones

    bbjones

    Joined:
    Feb 1, 2016
    Posts:
    85
    I got an email saying this is now fixed, but in version 2023.1x.

    No indication yet of backporting to 2021 LTS although I will try updating to 2021.3.6f1 LTS in the hopes it is fixed there too.

    Note that 2023.1.x isn't available even as a preview alpha/beta release yet.
     
    trombonaut likes this.
  23. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,646
    I am actively working on the backport. It is not fixed in 2021.3.6f1.
     
    DoctorShinobi and bbjones like this.
  24. Hazneliel

    Hazneliel

    Joined:
    Nov 14, 2013
    Posts:
    305
    Just updated to Unity 2021.3.5 and I'm encountering this problem too.
     
    trombonaut and jeremyfryc like this.
  25. eduqueirooz

    eduqueirooz

    Joined:
    Feb 22, 2021
    Posts:
    1
    same problem here :(
     
    trombonaut likes this.
  26. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,646
    The fix just landed to 2022.1.13f1. It's very close to landing to 2021.3 and 2022.2 release lines. Apologies for the delay. These changes are very delicate so we needed to be very thorough to minimize the risk of more regressions.
     
  27. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,646
    The fix landed to 2021.3.9f1. Here's what you can expect:

    • Primary display is now always the first display we return from Screen.GetDisplayLayout() API.
    • The first time you launch the game, it will launch on the display that Windows finds most suitable (generally, this means the display Windows Explorer or Steam was open on). This behaviour didn't change but I thought it's worth calling it out.
    • Next time the game starts, it will run on the same display that it ran on previously.
    • If the game last ran on the primary display and you change the primary display to another display, then next time the game starts it will run on the new primary display.
    • If you're upgrading from Unity 2020.3 and the game ran on the primary display, it will continue running on the primary display;
    • If you're upgrading from a broken Unity 2021.x version, then the game might start on the wrong display. You can work around it by calling Screen.MoveMainWindowTo() to display index 0 (previously, this wouldn't be the case on all machines), or manually move the window using WIN + SHIFT + arrow keys. Unfortunately due to the way this data is saved, we are not able to distinguish whether it was saved using older 2020.3 version or a broken 2021.x version so we treat it as if it was saved by a non-broken version.
     
    Marrlie, Shmardow, fnnbrr and 6 others like this.
  28. DoctorShinobi

    DoctorShinobi

    Joined:
    Oct 5, 2012
    Posts:
    219
    Thank you very much for fixing this and letting us know about it.
     
  29. toddw

    toddw

    Joined:
    May 9, 2010
    Posts:
    129

    So I just upgraded to 2021.3.15f1 and now the following workaround I've been using in 2021.3.4f1 is broken:

    Code (CSharp):
    1.    
    2.     void Awake()
    3.     {
    4. #if !UNITY_EDITOR
    5.         // fixes new Unity2021 bug where the secondary monitor was being chosen when the game launches in a release build
    6.         StartCoroutine("MoveToPrimaryDisplay");
    7. #endif
    8. }
    9.  
    10. IEnumerable MoveToPrimaryDisplay()
    11.     {
    12.         List<DisplayInfo> displays = new List<DisplayInfo>();
    13.         Screen.GetDisplayLayout(displays);
    14.         if (displays?.Count > 1) // don't bother running if only one display exists...
    15.         {
    16.             var moveOperation = Screen.MoveMainWindowTo(displays[0], new Vector2Int(displays[0].width / 2, displays[0].height / 2));
    17.             yield return moveOperation;
    18.         }
    19.     }
    I have 3 monitors on my windows 10 pro machine, the one in the center with "make this my main display" checked has an Identity of 1. As of Upgrading to 2021.3.15f1 my builds are appearing on my left monitor which has an identity of 2 and has "make this my main display" un-checked.

    Per your statement "Primary display is now always the first display we return from Screen.GetDisplayLayout() API.", I'm seeing that does not appear to be the case, given my code above, the value of displays[0] is neither the first monitor based on Identity nor is it the monitor configured with "make this my main display" checked.

    The good news is that after commenting out my workaround code and doing another build, manually moving the window using WIN + SHIFT + arrow keys did in fact work and then upon restarting the game it launched in the primary display as expected.
     
    Last edited: Jan 3, 2023
  30. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,646
    Hey @toddw, that is very unexpected. Could you by any chance show your monitor setup in the Windows display settings and also run this C# program on your machine and show its output?
     

    Attached Files:

  31. toddw

    toddw

    Joined:
    May 9, 2010
    Posts:
    129
    Yup, here ya go. Please let me know if you need something further.
     

    Attached Files:

  32. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,646
    Thanks. Can you also tell the me order Unity reports your monitors in (by looking at displayInfo.name)?
     
  33. fabrmooc

    fabrmooc

    Joined:
    Jan 13, 2023
    Posts:
    1
    Hi @toddw, it seems that the issue is with the StartCoroutine which isn't executed anymore. Calling directly MoveToPrimaryDisplay as a void function works for me.
     
  34. toddw

    toddw

    Joined:
    May 9, 2010
    Posts:
    129
    Interesting, just tested this and I'm seeing the same thing, the MoveToPrimaryDisplay method won't fire if called via StartCoroutine in the scope of Awake. Not sure if that is a new bug or a new fix in Unity's functionality. Either way I'm no longer calling the method anyway, but that is an interesting find, thanks fabrmooc.
     
  35. toddw

    toddw

    Joined:
    May 9, 2010
    Posts:
    129
    Sure.

    upload_2023-1-23_22-37-14.png

    In light of @fabrmooc's post I'm guessing my issue was the fact that the IEnumerable method when called via StartCoroutine in the scope of Awake is no longer executing in Unity 2021.3.15f1, which would explain why my solution suddenly stopped working as my first monitor in the array looks accurate. I suppose I should have used the Watch or Immediate window to verify the contents of displays[0] was indeed a display other than my primary, but I must have just assumed it wasn't given the behavior of the build, sorry about that, I should have been more thorough.
     
    Last edited: Jan 24, 2023
  36. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,646
    I'm glad it's resolved but I'm now worried about StartCoroutine misbehaving..
     
  37. SawyerK

    SawyerK

    Joined:
    Feb 11, 2016
    Posts:
    55
    Hi!

    Some players of my game reported the same thing, that the game starts on their second monitor and it keeps starting there every time they open up the game.
    I can't reproduce the problem because I only have 1 monitor.

    I use Unity 2019.4.40f1 LTS

     
  38. SawyerK

    SawyerK

    Joined:
    Feb 11, 2016
    Posts:
    55
    Any progress on this?
     
  39. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,646
    No, this is the first time we've ever seen this reported in Unity 2019.4. Unity 2019.4 didn't have any logic to remember which monitor it started on so I find the report weird. They can always use WIN + SHIFT + LEFT/RIGHT ARROW to move the game between different monitors, though.
     
  40. SawyerK

    SawyerK

    Joined:
    Feb 11, 2016
    Posts:
    55
    So, I should just tell them to use WIN + SHIFT + LEFT/RIGHT ARROW to move the game between different monitors?
    Or is there a script or something that I can use to make it more consumer friendly?
    Thank you for the reply!
     
  41. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,646
    Unity 2019.4 doesn't have any API or built-in capability to move a window to a different display. That was a new feature in Unity 2021.2.

    The only way to programmatically move the window is P/Invoking into MoveWindow win32 function from your C# script directly.
     
  42. Przemyslaw_Zaworski

    Przemyslaw_Zaworski

    Joined:
    Jun 9, 2017
    Posts:
    327
    This code works perfectly:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using System.Threading.Tasks;
    5.  
    6. public class Display : MonoBehaviour
    7. {
    8.     async Task MoveWindowTask (int index) // Minimum Unity Version required: 2021.2
    9.     {
    10.         List<DisplayInfo> displayLayout = new List<DisplayInfo>();
    11.         Screen.GetDisplayLayout(displayLayout);
    12.         if (index < displayLayout.Count)
    13.         {
    14.             DisplayInfo display = displayLayout[index];
    15.             Vector2Int position = new Vector2Int(0, 0);
    16.             if (Screen.fullScreenMode != FullScreenMode.Windowed)
    17.             {
    18.                 position.x += display.width / 2;
    19.                 position.y += display.height / 2;
    20.             }
    21.             AsyncOperation asyncOperation = Screen.MoveMainWindowTo(display, position);
    22.             while (asyncOperation.progress < 1f)
    23.             {
    24.                 await Task.Yield();
    25.             }
    26.         }
    27.         else
    28.         {
    29.             await Task.CompletedTask;
    30.         }
    31.     }
    32.  
    33.     async void MoveWindowAsync (int index)
    34.     {
    35.         await MoveWindowTask (index);
    36.     }
    37.  
    38.     void Update()
    39.     {
    40.         for (KeyCode keyCode = KeyCode.Keypad0; keyCode <= KeyCode.Keypad9; keyCode++)
    41.         {
    42.             if (Input.GetKeyDown(keyCode))
    43.             {
    44.                 string key = keyCode.ToString();
    45.                 int index = System.Convert.ToInt32(key[key.Length-1].ToString());
    46.                 MoveWindowAsync(index);
    47.                 break;
    48.             }
    49.         }
    50.     }
    51. }
    For main display call MoveWindowAsync(0);
     
    eco7 likes this.