Basically I would like to get notified (or poll) when the screen is rotated since I need a to use a different layout depending on the orientation and mainly because it currently keeps the same rendering resolution resulting in a very deformed viewport. This is a purely 2D game and I’m using Unity 5.3.6p1 building for Windows standalone and testing it on a Surface Pro 3 with Windows 10. I tested the same build on a desktop running Windows 7 to see if it was somehow related to the OS doing strange things in tablet mode: I started the build, minimized it, changed the orientation of the display through the “Screen resolution” window, went back into the game and got the same result: a game screen rendered at 1920x1080 but deformed to 1080x1920. If I switch to windowed mode everything gets updated properly so I think the problem only arises when in full screen, which is the main focus.
Ideally I would expect to get this information from either Screen.orientation or Screen.currentResolution, but these don’t update if the screen is rotated. I also tried getting Input.deviceOrientation but that returns “Unknown”. Considering that none of the UI elements rescale I assume that Unity just isn’t aware of the change when in full screen mode. I’ve tried all different PlayerSettings to no avail.
So I embarked on a different path trying to get the orientation directly from the Windows API which is available through Windows.Graphics.Display and creating a DLL which I was hoping to access through Unity but ran into a number of other issues mainly due to the fact that this API relies on .NET Framework 4.X which cannot be accessed in standalone from what I gathered. I created the project in VS 2015 Community as a Universal Windows Class Library in C#, created a function that returns the orientation, built the dll and copied it into Unity but I got the famous System.Reflection exception pointing to the System.Runtime 4.0.20.0 assembly not found in the Global Assembly Cache.
That’s right, I’m only targeting standalone since the game will be delivered through another store.
Yes, they both return the same values when rotating in full screen. If I Alt+Enter to switch to windowed mode and rotate then I do see the values change.
Thanks for the tip. Using GetSystemMetrics allows me to get the correct resolution, however Unity still thinks that it’s using the old one so even if I update the layout everything is still stretched. I tried using Screen.SetResolution but that doesn’t really help, Unity is still trying to render using the initial resolution.
For example starting the game in 1920x1080 and rotating to 1080x1920 gives those last values through GetSystemMetrics, but Unity is still rendering to 1920x1080. It needs to be notified that the physical display resolution has changed in order to update its render buffer. Is there any way to do this manually or is this something only internal?
It’s pretty easy to reproduce if you want to test. Create a new project and place a UI Image. No need to change any settings in the Canvas or Player Settings. Build and Run, and you’ll see your white square in the middle of the screen. Now either rotate the screen if you have a tablet, or just go to your display settings and either change the orientation or resolution to something else. Jump back into the game and see that everything is either stretched, cut off or offset depending on the resolution change. From what I can tell if you simply change the orientation and keep the resolution (inversed) it will still be full screen but stretched, if you change the resolution it will be a fake full screen like an overlay over your desktop.
Windows Standalone player doesn’t have a concept of device orientation… so no, there’s no internal or manual way to achieve this. This feature is simply was never done. Not sure, maybe you can play with camera’s aspect value.
Another way, maybe you can use Windows Store Apps?
I’ll add orientation implementation on our roadmap, so we can implement this in the future.
We cannot use Windows Store Apps since the game needs to be distributed through Origin. As far as I know creating a Windows Store Apps build won’t work, or will it?
As far as playing with the camera that won’t work simply because Unity is still trying to draw to an incorrect sized render buffer. This doesn’t necessarily relate directly to orientation, but to basically changing the display resolution through Control Panel while the game is running, which is actually what changing orientation does as well.
Here are some screenshots that might clarify the issue:
The first one is when starting the game at a set resolution of 1920x1080.
The second after changing the resolution to 800x600 (it’s not cropped, just what I can see full screen).
The third when going back to 1920x108 and changing the orientation, which is equivalent of having a 1080x1920 resolution.
Going through Control Panel to change resolutions while the game is running is a pretty low user path, but changing the orientation of a tablet can be quite common. Is there absolutely no way to refresh the size of the render buffer without restarting the application?
Yes, tried that as well as forcing the resolution, but it always reverts to the one used when the application was started. I think Unity probably stores those values somewhere and uses them when rendering full screen, even if the actual resolution was changed by the OS in the meanwhile.