Screen design for mobile game UI can be very daunting. There is a very broad range of device resolutions, screen sizes and aspect ratios to accomodate. It’s not viable for independent artists or small teams to design a new visual layout for every screen.
What you need is a framework that allows you to use a single design across all devices.
In the past, you could attach UI elements to screen borders, just specify a vertical field of view, then aim for 9:16 and automatically allow more vision on the sides on wider devices like iPads. However, with the rise of taller screens like the iPhone X, now that you face aspect ratios narrower than 9:16, meaning this approach is no longer viable. The vertical field of view will crop key elements out, and attaching UI elements to screen corners puts them far out of reach or in conflict with system gestures.
The most professional solution is to make a bespoke design for every key device type. However, I work mostly independently and don’t have time or money to multiply my workload that way. Instead, I’ve assembled a little design framework that elegantly accommodates a screen of any aspect ratio.
My Mobile Game UI Solution
This framework is composed of four elements:
- The fundamental construction of your screen is done at 360×640 resolution. While this doesn’t line up to an existing Apple device point resolution, it has a number of benefits:
- Easily divisible, including by 2, 3, 4, 5 and 8, allowing for elegant construction grids.
- Exactly one third of Full HD (1920×1080) on each axis, which is the native pixel resolution of iPhone 6+/7+/8+ and a common Android device resolution.
- The low resolution is very human-friendly for rapidly tweaking and repositioning elements.
- Considering the pixels per centimetre of modern devices, pixel-aligned imagery is not a large concern.
- A Unity canvas configuration that scales your UI to always fit on screen and behave consistently.
- Canvas Scaler component set to “Scale with Screen Size” to resolution 360×640.
- “Screen Match Mode” set to “Expand”, meaning differences in aspect result in space being added, not removed.
- All UI elements are placed inside an empty 360×640 gameobject on the canvas. Combined with the scaler settings, this allows us to not care about the anchors or pivots of our objects. Any UI element placed within this 9×16 rectangle will stay in their position – screen aspect changes will only add space on the outside.
- A canvas grid gizmo script that overlays your desired grid in the viewport, so you can match your design closely.
- A camera script that takes control of your field of view, making it driven by the vertical angle when the screen is wider than 9:16, and swapping to horizontal angle when it’s narrower. This makes sure the viewport always expands out from your desired aspect ratio, meaning the visual behaviour matches the UI
Additionally, I have included a sample project, if you would like to investigate how it works.
Download
You can get the framework from github, or download the unitypackage.
I hope this removes some headaches from your process, and don’t hesitate to drop me a line if you end up using it, or if you run into any problems with it.
Hey mate,
Nice work on the package, definitely interested in adapting and rolling a version of it my own development toolset.
I also noticed that there is an infinite loop that is created when the grid size is set to zero or less in the inspector that I thought you would want to know can occur.
Keep up the good work 🙂
Thanks for letting me know, Gerard (and sorry for crashing your editor). Hope we can catch up sometime soon! 🙂
hey Alex, this is an awesome editorial that I found super useful. I started using it for some of my projects at work and it’s been a great addition to my Unity toolset. Keep up the amazing work, can’t wait to see what you make next.
PS: nice to see you again, we should catch up again sooner rather than later! 😀
wow great job!
One doubt, what would be the correct resolution and dpi’s to insert an image or video on the grid and that would look good when rescaled at a higher resolution (for example at an iPhone X resolution)?
thanks!
Hi James, the best resolution is one that’s designed to match your target pixel dimensions. I may not be understanding your question correctly here though!
Thanks for answering.
I wanted to say that if we use images for a resolution of 360 x 640 by default, when the image is extended to rescale at a higher resolution (for example IPhone X) if it could look bad, having a lower definition the original image.
On the other hand, in the Main Camera Unity warns me that the GUI Layer component is deprecated, is it a problem or should it be changed by another updated component?
Thank you very much for your work.
Right, I see what you mean. The key to understand is that the the resolution of your images/assets is seperate from the units in your design. I generally author my images at 3x size (so 1080×1920 to cover a whole 9:16 screen). Modern design tools like Sketch generally have built-in features to handle this for you.
As for the GUI Layer component, just remove it from your camera, it’s not required for anything.
Hello Alex,
What a nice tiny framework!
We have a prefab “SimpleAspectRatioCanvas”. How can it be used?
It is not used in Sample scene.
Thank you so much!
The canvas object in the sample scene is the same as that prefab, guess I forgot to replace it!
It allows you to put things inside the “Fit Content” object and they’ll always appear in the same area relative to the centre of the screen.
Hey Alex,
Great work here. This came in very handy for me! Just thought I’d pass on something I learned while following your advice, and using your scripts.
The PerfectFOV script will make changes to the fieldOfView of Camera.main, so if you have multiple cameras/multiple scenes loaded in your game, it doesn’t always update the FOV of the correct camera.
A simple fix that worked for me was to use Awake () to make a reference to the Camera component in the script, and then use that in UpdateFOV instead of Camera.main.
Hope this helps anyone else who may be encountering this issue.