Update Feb. 3, 2017: I’ve updated the post to reflect more testing and newer methods to attain resolution independence in Unity.
Over the past couple of weeks, I’ve come to realize that developing a truly resolution independent user interface is not easy, especially for desktops and laptops. I’ve read a lot of posts and tutorials online, experimented with various methods, performed a lot of tests, and I’m still unsure of the best route to take. What makes it even more difficult is that nowadays (2015 as of the time of this post) we have an even greater variety of screen resolutions to design and account for, from lower resolutions like 1024×768 up to 4K (3840×2160).
From what I’ve seen, there are 7 general methods, and combinations thereof, which developers use to create a UI for different resolutions. The first 6 use the relatively new Unity UI system. I’ll list the advantages and disadvantages and offer my thoughts on each:
1. Make a non-scaling UI (in Unity, this is a UI with Constant Pixel Size set for the UI Scale Mode of the canvas) with panels anchored to various edges of the screen.
- Can create bitmap images at exactly the size you need, and have them be very crisp and sharp on screen
- Design at the lowest resolution you need to support to make sure no elements overlap, and you should be good.
- Can have very small pixel perfect fonts, if that’s what you need.
- UI doesn’t scale, so the UI will tend to be very small at resolutions like 4K, and will take up a lot of screen space at low resolutions.
- In my experiments, with a generic window panel in the middle of the screen, it will take up the whole screen at 1024×768, and will be a very small panel in the middle of the screen at 4K.
Looking at the Steam Hardware Survey, as of October 2015, there are 4 times more people using a 1024×768 monitor than those using 4K, although this will probably change over the next few years. If we want our games to last and work well as display resolutions increase in the future, we need to account for these sizes and perhaps more.
The above technique, while viable when we only needed to design up to HD (1920×1080), doesn’t seem that practical nowadays with such a huge range of resolutions. If we only need to anchor some elements to the corners of the screen, or there are very limited ranges of resolutions we need to support, then this technique can be useful.
2. Create multiple assets for various resolutions (like SD, HD). For example, larger images for larger resolutions, and smaller images for smaller resolutions. Set text sizes for various resolution ranges.
- This technique also seems to be useful for more limited ranges of resolutions, and allows pixel perfect crisp images and texts.
- Can become a headache to manage all the various assets and sizes of panels. With the advent of 4K, we may even need 3 sizes of each asset – SD, HD, and UHD.
- This becomes problematic with complex UIs with lots of elements next to each other. When you swap out assets at different resolutions, the sizes of elements will change, making it difficult to keep things relative to each other.
This technique also tends to be more useful for simple UIs, or things anchored to corners. With complex UIs, this technique quickly becomes unusable unless you use lots of layout groups. If your animations rely on certain sizing, this technique may require a lot of extra work depending on the complexity of the UI.
3. Create a UI Canvas that scales (in Unity, set UI Scale Mode to scale with screen size) using bitmap images.
- You only need to create one version of the UI that will always take up the same proportions of the screen no matter the resolution.
- Let’s say you design all your bitmap images for the largest resolution. For lower resolutions, this might be ok if the images are relatively large, as downsizing usually produces better results than having to upsize. But if screen resolutions larger than what you designed for become popular, then your images will need to be upscaled, losing quality. Also, sometimes the downsizing produces artifacts in the images.
- Thin lines, edges, and text become blurry and unclear at different resolutions, even with pixel perfect enabled. Sometimes artifacts show up, or lines simply disappear as there are not enough pixels to reproduce the item at low resolutions. You may need to play with various settings of the texture importer, like whether to generate mip-maps for the chosen image, whether to use Point vs Bilinear or Trilinear filtering, etc.
No one wants to see a blurry UI, especially one with artifacts. Using the default text component in Unity, unless you decide to set the text sizes manually for different resolutions, will result in illegible text when the canvas scales to certain resolutions. One fix for this is using the technique of setting the font material to point filtering as explained in this post in the Unity forums.
4. Create a UI Canvas that scales with screen size using vector graphics (SVG).
- Relatively crisp UI at all resolutions, as vector graphics scale beautifully.
- Just like #3, you only need to design the UI at one resolution, and have it scale nicely to all other resolutions.
- As of now, cost. There is no built-in functionality in Unity for vector graphics, and you’ll need to buy one from the Asset Store.
- You will need some form of antialiasing for the edges, whether MSAA or some form of post processing AA, or shader-based antialiasing. This will cause some sort of performance hit, depending on the platform you’re developing for, and the method you’re using.
- Possibly blurry text at different resolutions unless you use this technique or use a more robust third-party asset (see below).
This seems to be a good method of doing resolution independent UIs. The text problem can be solved by using a third-party asset like the newer I2 SmartEdge or Text Mesh Pro. In my testing, the multi-channel signed distance field font rendering of I2 SmartEdge results in more legible fonts at very small text sizes compared to the regular signed distance field method of the very popular Text Mesh Pro. It seems like I2 SmartEdge development is on hold due to Unity integrating Text Mesh Pro natively. Results may vary based on the settings and the type of font used for both text assets.
5. Use a UI Canvas that scales with screen size with SDF textures
- Crisp edges of UI images at all resolutions.
- Like #3, you only need to design the UI at one resolution, and have it scale nicely to all other resolutions with just one asset per image.
- Cost as it requires purchasing an asset from the Asset Store.
- Fiddling with the settings and some testing to get the best generated SDF texture.
This is the method I found that gives me the best results. You can use an asset like SDF Toolkit or I2 SmartEdge to generate the SDF texture and use that for the UI images, which scale well at all resolutions with the right settings of the spread factor, softness, etc. You can also use Text Mesh Pro to generate the SDF font textures for all text. See #4 for more details about text.
6. Use a UI Canvas that scales with screen size with procedural UI shapes
- This gives resolution independent UI elements, albeit using primitives with various numbers of sides only.
- You don’t have to worry about lots of various UI textures.
- Cost, as you usually have to buy these assets from the Asset Store, unless you use the generators from the free UI Extension project, but then you’ll get jagged edges unless you use MSAA, which leads to lower performance and more memory usage.
- Need to find an asset that uses shader based antialiasing, otherwise you get lots of jaggies.
This is a pretty good alternative to having to create the elements yourself. The ones I found that fit my requirements: Shapes2D or Procedural UI Image. There are others if you do some searching on the Asset Store.
7. Use a vector UI system like NoesisGUI, Scaleform, or Coherent UI.
- Like #4, design once and have it work at all resolutions.
- Crisp images and fonts.
- Depending on the system, GPU accelerated.
- Cost… these UI packages can cost quite a lot depending on the licensing. NoesisGUI is now free however for Indie’s under a certain income limit, which is really cool.
- Need to learn a different UI system, possibly different tools, and all the quirks associated with each. Some of them use different programming languages like XAML, HTML, etc.
- Slight performance hit of using antialiasing, though these solutions tend to have efficient methods of implementing it.
These systems seem to be what many bigger game studios use and are nice for having there be a separation between the UI and the code behind it. There will be a bit of a learning curve for these systems, depending on your current knowledge.
Currently, I’ve settled on #5, using Text Mesh Pro for fonts, and SDF Toolkit for images. It’s really convenient to just design it once and have it work for all resolutions. I hope this post has at least given someone a better idea of the various options for producing a truly resolution independent UI. If you’ve discovered more methods, please let me know in the comments below. Thanks!