Through example, we explore methods of creating a responsive UI in Unity.
In this context, being responsive means that the UI reacts appropriately to varying screen sizes and densities.
note: This article assumes that one has a basic understanding of Unity; I found the no-cost course Learn Unity 3D for Absolute Beginners particularly helpful.
Starting from a new 3D project, we add a Canvas game object and add colored buttons (width and height are 100 px) to it at its four corners.
The first problem you will observe when resizing the game window is that the buttons get cut off.
This is because the buttons are anchored relative to the center of the canvas which shunk to match the game window, e.g., the red button is 200 px to left and 125 px above the center.
Our first fix is to anchor the buttons to the respective corners of the canvas; modifying the button’s Rect Transform component, e.g., the red button is 75 px to the right and 75 px below the upper-left corner.
While staying within the game window, the next problem is that the buttons now take up a disproportional amount of the game window.
In order to appropriately scale the buttons to the game window, we use the canvas’s Canvas Scaler component. We change it from the default, Constant Pixel Size, to Scale with Screen Size.
You will immediately notice that the buttons appear proportionally smaller.
Let us understand what happened.
First, you will noticed that the Canvas Scalar’s default resolution is 800 x 600px. Second, you will notice that the Screen Match Mode is Match Width or Height and Match is set to 0 (more on this later).
With this configuration, the buttons are scaled based on the width of the game window.
scale factor = game window width / 800
As shown, the game window width is 400 px; thus with the computed scale of 1/2 the buttons are displayed 50 x 50px. Notice that changing the game window’s height has no effect on button size.
The problem now, however, is that if we have a wide game window (around 800 x 200px) our buttons (100 x 100px) again take up a disproportional amount of the game window.
The complete scale calculation (as far as I can tell) is:
scale factor = (game window width / 800) * (1 - match) +
(game window height / 800) * (match)
So, with a match of 0.5 the buttons are displayed again more proportional to the game window again.
As a matter of fact as long as the aspect ratio of the canvas scalar’s default resolution is roughly comparable to the game window, setting the match 0.5 is a fairly good value to use for a responsive UI.
By setting the Canvas’s Render Mode to World Space we place the UI into the 3D world.
In this mode, you have the ability to set the canvas’ width and height; in this case we set it 800 x 600px (same as the canvas scalars’ default resolution above). Also, to scale down the UI to fit alongside other 3D elements, we set the Rect Transform’s Scale to 0.01 (both X and Y).
Interestingly enough, while rendered in World Space, the canvas’s Canvas Scaler no longer supports the earlier scaling options. This effectively means that we cannot make the canvas responsive as we had done before. At the same time, we are in full control of its width and height; so being responsive is not terribly important.
In the end, we learned that we can make responsive an UI when the canvas is rendered in Screen Space — Overlay by configuring its Canvas Scalar.
We also learned that when the canvas is rendered in World Space, we loose the ability make the UI responsive. But, then again, in this case we are in full control of its width and height.