Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Unity hosted in Windows Forms has weird aspect ratio

Discussion in 'Windows' started by Dustin27, May 17, 2022.

  1. Dustin27

    Dustin27

    Joined:
    Nov 12, 2018
    Posts:
    15
    Hello,

    in our software, we show an Unity game in Windows Forms. Also, we provide the possibility for the user to adjust all window sizes by dragging with the mouse (using Krypton Workspace).

    The problem is when the user adjusts the size of the Unity window, the game possibly shows weird visual behaviour.
    • A) With default scaling, everything is ok.
    • B) When the game's window width is decreased, then Unity decreases its width even more and fills up the remaining space with a repeated screen.
    • C) When the game's window width is increased, then Unity increases its width even more, resulting in cut off screen.
    Sometimes the game even starts with behaviour C).

    The resolution that is given by Screen.width and Screen.height is always the correct one of the total bounding window (stated at the bottom in the images).
    So I tried calling
    Code (CSharp):
    1. Screen.SetResolution(Screen.width, Screen.height);
    but that did not change anything.

    Is there a possibility to trigger a refresh so that Unity shows everything correctly again after resizing?

    Images:


     

    Attached Files:

  2. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,516
    You might have to call the Windows SetWindowPos API with correct bounds to get it to resize properly when your Windows form is resized.
     
    Dustin27 likes this.
  3. Dustin27

    Dustin27

    Joined:
    Nov 12, 2018
    Posts:
    15
    Thanks for your reply. Calling SetWindowPos with the Location and Size of the UserControl (that contains the game) had no effect unfortunately so it seems that the window already has the correct parameters.
    (Btw, I also tested if SetWindowPos works generally and yes, with half the width of the UserControl the game only occupied half the space)

    Is there anything to fix this behaviour in Unity?

    Edit: I checked if the Camera actually has the correct "pixelWidth" and "pixelHeight", and yes it has the same correct size as the window:
    upload_2022-5-18_14-42-49.png
     
    Last edited: May 18, 2022
  4. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,516
    Can you show the code where you call SetWindowPos?
     
    Dustin27 likes this.
  5. Dustin27

    Dustin27

    Joined:
    Nov 12, 2018
    Posts:
    15

    In my User Control I got this method:
    Code (CSharp):
    1.         public void RefreshWindowPosition()
    2.         {
    3.             Win32.SetWindowPos(unityWindowHandle, IntPtr.Zero, Location.X, Location.Y, Size.Width, Size.Height, (int)SWP.SHOWWINDOW);
    4.         }

    It calls this extern method in the Win32 class:
    Code (CSharp):
    1.     [DllImport("user32.dll")]
    2.     public static extern bool SetWindowPos(IntPtr handle, IntPtr handleInsertAfter, int X, int Y, int cx, int cy, int uFlags);
    3.  
    4.     // ...
    5.  
    6.     public enum SWP
    7.     {
    8.         // ...      
    9.         SHOWWINDOW = 0x0040,
    10.     }
    I am calling "RefreshWindowPosition" from another thread but I also tried calling it with a subscribtion to "UserControl.Enter":

    Code (CSharp):
    1.         public Viewer3DUC(Viewer3D host) : base(host)
    2.         {
    3.             Enter += (s, e) => RefreshWindowPosition();
    4.             // ...
    Both did not bring the expected result.
     
  6. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,516
    I'd try using spy++ to see if WM_WINDOWPOSCHANGING message ever arrives to Unity window. Perhaps it gets lost somewhere along the way (spy++ would show you that).
     
    Dustin27 likes this.
  7. Dustin27

    Dustin27

    Joined:
    Nov 12, 2018
    Posts:
    15
    upload_2022-5-24_10-5-32.png

    I set up a timer that calls SetWindowPos every second and according to Spy++, Unity received the message but the outcome is still not correct. :(
     
  8. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,516
    What is Screen.fullScreenMode that Unity reports? Did you print out numbers to see if you're sending the right resolution to SetWindowPos API?
     
    Dustin27 likes this.
  9. Dustin27

    Dustin27

    Joined:
    Nov 12, 2018
    Posts:
    15
    upload_2022-5-26_11-0-7.png

    Screen.fullScreenMode is Windowed (and Screen.fullScreen is false).

    The resolution I am sending is:
    Size: {Width=843, Height=594}

    Code:
    Code (CSharp):
    1.         public void RefreshWindowPosition()
    2.         {
    3.             Log("Size: " + Size);
    4.             Win32.SetWindowPos(unityWindowHandle, IntPtr.Zero, Location.X, Location.Y, Size.Width, Size.Height, (int)SWP.SHOWWINDOW);
    5.         }
     
  10. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,516
    If Screen.width/Screen.height return the right resolution, something else is off - Unity thinks it is rendering at the right size. Is your parent app DPI aware? What's the monitor scaling you're running it on?
     
    Dustin27 likes this.
  11. Dustin27

    Dustin27

    Joined:
    Nov 12, 2018
    Posts:
    15
    Yes its DPI aware and the monitor scaling was 1080x2580 and later 1440x3440.

    We currently try another tool than Unity for our purpose. The difference between Unity in the editor and once it is built and runs inside WinForms caused too many problems.