Recently, we have a performance issue on our macOS build. The game runs smoothly in low-end Windows laptops but laggy in a 2016 Macbook. Although the hardware of the Macbook is not even as good as the Windows laptop, we doubted the performance would be much different. In addition, it runs alright in Editor in Macbook but not in a build, so the hardware influence should be able to be ignored.
Spotting the Problem
After fighting the issue for a while, we’ve found that if we switch from the default full-screen mode to the window mode, the window is very large (almost 4 times as the monitor size). This high resolution runs even in full-screen, dragging down the performance and frame-rate of the game.
This may be because either we enabled Mac Retina Support, or we make the build in a high-resolution iMac and the default resolution is saved with the game build. I didn’t bother the figure out the reason but going straight into the solution.
Solution — Fixing the screen width
The first thing we do is manually setting the resolution with a script on game start:
int manualScreenWidth = 1920;
Screen.SetResolution(manualScreenWidth, Mathf.RoundToInt(1f * manualScreenWidth * Screen.currentResolution.height / Screen.currentResolution.width), Screen.fullScreen);
This set the screen width to 1920, and the height to proportional to the player’s monitor size (Screen.currentResolution). For example, in modern 16:9 monitors, it set resolution 1920×1080. This works pretty well in both full-screen mode and windows mode until the player changes the size of the windows manually…
Another problem — Letterbox
If the player set the window to be very narrow in Windows Mode, then entering Full-Screen mode will result a letter-box:
This is a very unwanted behaviour, we simply want the game to take all space when it goes into full-screen mode. This is actually the designed behaviour from Unity and Unity seems intend to keep the letterbox instead of stretching the resolution (I doubted if any developer prefers this). This has also been asked multiple times.
Solution for full-screen mode
After some search, I couldn’t find a very promising solution and decided to come up with my own one. I wrote a script that takes account for:
- Game is built-in default full-screen mode
- Use this script to:
- When changing from full-screen to window mode: set the width to 1920 and height proportional to monitor size (
Screen.currentResolution), save both width and height in
- When changing from window to full-screen mode: set the width to 1920 and height proportional to the saved width/height ratio.
The reason we need
PlayerPrefs to save the width and height is that, Unity cannot obtain the monitor size in full-screen mode.
Screen.currentResolution gives the current resolutions (the window size in window mode). There may be an even better solution using
Windows.System.Display, but using
PlayerPrefs is good enough, while the game is full-screen by default. Let me know if anyone knows another way to do it.
|Window Mode||Full-screen Mode|
|Screen.width||Window width||Width in current resolution (Window width set before, or width set in Screen.SetResolution)|
|Screen.height||Window height||Width in current resolution (Window height set before, or height set in Screen.SetResolution)|
|Screen.currentResolution.width||Same as Screen.width||Same as Screen.width|
|Screen.currentResolution.height||Same as Screen.height||Same as Screen.height|
Notes that I only set the manual screen width in Mac, and leaving the screen width in Windows to
Screen.widthso it uses the maximum resolution.