UI Design Starter Guide

In this guide I will be showing you some good practices for graphical user interface (GUI) design, as well as how to make GUIs in Roblox.

Ultimately what you should do is up to you; I might have good advice, but there will always be exceptions. Design is a flexible discipline. Feel free to mess around or do things that are “wrong”. Just remember that you want to provide a good experience for your players, and a confusing or annoying UI will not help you in that goal.

I have reached the maximum character limit of 32000 characters on this guide (and there were already lots of replies by the time this happened) so I had to put the things not covered here (UI objects, ViewportFrames, tips) in a new topic: UI Design Objects & Tips
Please read this guide first.


Size & Position

UDim2

Roblox GUI objects have all of their measurement done by a value type called UDim2, which stands for Universal Dimension 2 (as in it is comprised of 2 UDim values).

A UDim value consists of two numbers: Scale and Offset. Scale is a measurement based on the screen size - the number 1 would represent the entire size of the screen, and 0 would represent nothing. This also has compatibility for negatives and numbers larger/smaller than 1/-1. Offset is simply a measurement of pixels.

Example of UDim2

Screenshot_204
A Frame being the horizontal size of its parent - minus 40 pixels - and being 30 pixels high.

Explanation of Scale and Offset

Scale is flexible and always refers to a portion of the screen size OR the size of the object’s parent GUI object. Scale is better when you need to have something that covers the whole screen, or when you need to position something in the center of the screen. In essence, Scale changes based on the same screen size.

Offset is essentially referring to pixels on the screen. This is better when you need pixel-perfect accuracy, such as displaying an image at maximum crispness or when you need to make something exactly 3 pixels away from the edge of the screen. In essence, Offset values will always stay the same, no matter the screen size.

Tip: Here are some interesting ways to use scale.

  • Using Scale for the size property in the BillboardGui object makes it resize automatically based on distance instead of staying a fixed size on your screen.
  • Using Scale to make health or progress bars. This makes it really easy for the scripter to code, as when calculating the size of the bar, the final result they need to get will stay the same no matter the actual size of the GUI (i.e. it will usually be a number from 0 to 1).

Using Size and Position

Note: The problems I will mention in this section are often why the UI you designed in Studio looks different in-game. When using Scale - or when, in fact, using anything at all - you will usually design to look good in a specific screen size which is usually the size you have the screen set to in studio. This often leads to elements not looking right when playing outside of studio.

Since I originally wrote this guide, my views on how to make good UIs in Roblox have changed. Originally I thought Offset should be used all the time except for when you specifically need something that scales (like a frame covering the entire screen) in which case Scale should be used.

The reason I had for why Scale shouldn’t be used was because it wasn’t easy to make objects using Scale keep their shape (more commonly known as aspect ratio, I will use this term from now on).

Example of scale being bad

Frame with Size {0.4, 0}, {0.5, 0}.
On a tablet, this frame looks like a square:


But at a different aspect ratio, like on a really wide screen, it suddenly becomes a big long rectangle:

Why is keeping aspect ratio important? Because many parts of your UI will need a similar aspect ratio to look good on different devices.

For example, images stretch at different aspect ratios


This is why originally I decided that Offset was better than scale – because the aspect ratio remains the same no matter what.

But as it turns out, Offset is not very good either, and for support on multiple devices will require redesigning your UI multiple times. When you size or position something using Offset, it won’t change anything when the screen size changes and so it becomes difficult to use the same UI on different devices.

Example of offset being bad

Frame with Size {0, 600}, {0, 600} and Position {0, 340}, {0, 60}
On a 1280 x 720 screen:


On an iPhone 7 (667 x 375) where you can only see the top left corner of the frame:

So it looks like both Scale and Offset kinda suck on their own. What do we do then? Well as it turns out, the core problem here is that we need our GUIs to maintain aspect ratio. And there are two great solutions to this Roblox has: the UIAspectRatioConstraint, and the SizeConstraint property of GUI objects. These will be covered later in the guide.

So now that we have solved the problem of aspect ratio, which one should you use? The answer in my case is Scale. I make my UIs 100% in Scale unless I have a specific need for offset. All three of my recent games have had only a single UI that scales perfectly across all devices, and with almost no Offset use at all.

AnchorPoint

All GUI objects also have a property called AnchorPoint. This property is a simple Vector2 where each of its values range from 0 to 1 - similar to the Scale value in a UDim. The anchor point defines where the position will be applied to.

Currently, this frame has an AnchorPoint of 0,0

Screenshot_221
Screenshot_220
The frame is being positioned from the top left corner, so that anchor point will be where the frame’s Position property is.

Alternately, you could set the AnchorPoint to 1,1 so it will be positioned from the opposite side

Screenshot_222

Or, you could even change it to 0.5,0.5 so the object would be positioned from its center like Parts are

Screenshot_223

AnchorPoint's main function is make to positioning GUIs easier and let you use less brainpower trying to calculate the position. This allows you to simply position an object at the bottom of the screen using a Position.Y.Scale of 1 - as long as the Y property of the AnchorPoint property is set to 1, the object will also be fully visible.

For example, AnchorPoint is set to 0,1 and Position is {0.3, 0}, {1, 0}

Screenshot_225
Screenshot_224

AnchorPoint is a really useful, so you should definitely be using it in your UIs when it could make things easier.

ZIndex and DisplayOrder

There’s a property in every GUI object called ZIndex that defines what is in front and behind of it. This defines whether an object is in front of another. A higher ZIndex is in front of a lower ZIndex.

The ZIndex property only affects objects within a single ScreenGui, so objects from two different ScreenGuis will always display separately regardless of ZIndex. Instead of the ZIndex property, ScreenGuis have a similar property called DisplayOrder. This determines whether the ScreenGui is in front or behind of other ScreenGuis.

Maintaining aspect ratio

As shown in the Using Size & Position section, maintaining aspect ratio is an important thing we often need to do in Roblox GUI design. There are two main methods for doing this.

SizeConstraint property

(Offset is unaffected by SizeConstraint, as it is based in pixels, so this only relevant for Scale.)

All GUI elements have a property called ‘SizeConstraint’ that lets you define what way an object’s size is calculated. There are 3 possible values for this property:

  • RelativeXY
  • RelativeXX
  • RelativeYY

If we have RelativeXY, that means the X axis is sized according to the horizontal (X) size of the screen, and the Y axis is sized according to the vertical (Y) size of the screen.

Frame sized {0.5, 0}, {0.5, 0} with RelativeXY

If we have RelativeXX, that means both the X and Y axes use the horizontal (X) size of the screen. This means if you make a frame have the size {1, 0}, {1, 0} with this constraint, the frame will always be a square, no matter how tall the screen is, because its using the horizontal size to calculate the vertical size.

Frame sized {0.5, 0}, {0.5, 0} with RelativeXX

(Overflows outside of vertical screen space because half of width of screen is bigger than height of screen)

Conversely, if we have RelativeYY, that means both the X and Y axes use the vertical (Y) size of the screen. Same deal, it will always form a square because it uses the vertical size to calculate the horizontal size.

Frame sized {0.5, 0}, {0.5, 0} with RelativeYY

One thing you may have picked up is that if you’re using XX or YY, an object will always stay the same aspect ratio no matter what the screen size is. This is why it is useful.

Let’s imagine that you wanted to make a frame that is always twice as wide as it is tall. You could set the SizeConstraint to RelativeYY, then set the size to {2, 0}, {1, 0}. Yup, it’s that simple.

Now being more practical here, you want to make it 0.5 (half) of the screen’s height so that it doesn’t cover everything. The size required for this is {1, 0}, {0.5, 0}. What happened to the 2? The important part here is that to keep an aspect ratio, you need to always make things relative to the dominant axis (in this case, Y). So if you want width to be double the height, it should height * 2, which in this case is 0.5 * 2 = 1.

I usually use RelativeYY instead of RelativeXX, as in my experience the best scaling occurs when you base things off of the screen height and not the width. Most screens tend to be wider than they are tall, so often being within the vertical height of the screen will guarantee good scaling.

This is my preferred method of maintaining aspect ratio. It’s a lot quicker and less confusing to use than the UIAspectRatioConstraint. Using only this property, I can make an entire UI that scales very well across multiple different screen sizes and aspect ratios.

Tip: If you need objects to maintain aspect ratio inside a vertical ScrollingFrame, use RelativeXX. Otherwise basing their size off of the height will make the size get bigger as the CanvasSize increases, which is not a good thing. You can use the opposite (RelativeYY) for a horizontal ScrollingFrame.

UIAspectRatioConstraint

This object allows you set the aspect ratio of anything, including cells within layouts such as UIGridLayouts (if you put the UIAspectRatioConstraint inside the Layout object). You can read about it in some more depth here: UI Design Objects & Tips


Text

Scaling

All objects that have text also have a property called TextScaled which is a bool of whether the text will resize itself to fit the size of the object is being applied to. It is useful if you are making text that scales with your UI, and also if you’re being lazy about the size of UI elements.

A common gripe of mine with text in Roblox is that people frequently use TextScaled without concern for what it actually looks like in the end. This often results with buttons in the same visual group having different text sizes, which just looks weird and inconsistent.

Here's some buttons with and without TextScaled being used badly

With TextScaled used badly
Screenshot_202
Without TextScaled being used (still ew – but better)
Screenshot_203

Colors

You may or may not have noticed that some colors at their fullest brightness still appear to be darker than other colors - for example, red or blue - and some colors are still bright.

In other words, "visually dark" colors like blue, purple and red are hard to see in front of a dark background.

text_bluetext_red

But these lighter colors are easier to see

text_greentext_yellow

Note that the opposite of this is also true. Brighter colors like yellow and green are harder to see in front of a white background.

Due to this, you will want to consider what color your text is. A good rule of thumb: Use white text as much as possible (or other bright colors). It’s generally easier to see than dark colors, unless the rest of your game OR the GUIs are bright. If you really want to use a specific color, like blue, consider changing the lightness of the blue color, or adding extra things like stroke or a background.

Stroke

All text objects have two properties: TextStrokeTransparency and TextStrokeColor3. These are self-explanatory; one is the transparency of the stroke, the other is the color.

It is generally a good idea to have TextStrokeColor3 always contrast with the TextColor. If there isn’t contrast, the text starts to lose its defining shape and clarity, becomes harder to read, and doesn’t look that great (although in this case it can used as a glow effect).

Example

Screenshot_228

Alternatively, if a different stroke color is used, the text is clear and easy to read, looks pretty nice, and the text can also be read in front of any background as the stroke separates the text from the background.

Example

Screenshot_227

Stroke is very useful for white text as a transparency of 0.8 allows for that barely visible amount of shadow that distinguishes it from the background.

Background

An important thing to remember for text is what is behind it.

A cluttered background behind text can hide letters in a sea of varying color. The text becomes just another meaningless pattern.

Usually you’d want to keep what is behind the text fairly simple so people can easily read the complex symbols that make up the alphabet:

Not very good

Screenshot_229

Good, could be better

Screenshot_230

For comparison

Screenshot_231

You can see that the text with the blurred background is easier to see - this is because blurring essentially simplifies an image. It becomes less cluttered, and sharp shapes are now contrasting with smooth, fading shapes.

The text with the plain background is even easier to see - there is nothing behind it conflicting with the text.

Wrapping

Text wrapping occurs when text automatically creates a new line when it has reached the edge of the space it can fill. You see it in almost every word processor like Word and Google Docs, when you type too many words to fit in the screen it puts it on a new line.

This is an example of text wrapping

Screenshot_232

And this is an example without it

Screenshot_233

While it is incredibly useful for long bits of text in say, an essay, it is not as practical when using buttons. Sometimes it can make the text either go to a new line that can’t be seen or will change the text size when using TextScaled. Generally I think it’s a good idea to avoid wrapping text in buttons, either by resizing the button or making the text smaller or disabling TextWrapped, just so that all of the buttons have a similar appearance. This will all depend on your style of course.


Images

Images are very important as they open up a whole new range of custom shapes. The ROBLOX 2D engine is rather limited in the shapes it can provide, so uploading custom shapes is always helpful!

Often using unique images helps give your game identity and also can work with immersiveness. Making a cartoony game? Use big, round shapes and bold text!

Making a western game? Give all of your UI elements a wood grain texture!

Size

The size of an image can have a significant effect on what it looks like. Generally it’s not a good idea to use an image at a size bigger than what it was made for, e.g. if you have 10x10 image don’t use it at 100x100 because it will look pixelated and blurry.

Less importantly, images in Roblox will look the most crisp when used at their original resolution – so if you’ve got that 10x10 image, it will look the best when used at 10x10 size. Offset can come in handy to make sure an image is always at its original size. However, this crispness is not very important for most games as people don’t really care that much, and to use it you would need to support multiple screen sizes (which means if you wanted to do this, you would need a version of the image for all the different screen sizes.) I wouldn’t bother with this if I were you.

Black edges

Often when you upload an image to Roblox and then use it a size different than its original size, it will be given a subtle black outline. This can be annoying sometimes, although it is another minor detail. In my work I use the tool PixelFix to solve this efficiently: Pixelfix: Remove the black edges on scaled images

Here’s an article written by Quenty about this problem, why it occurs, and how you can fix it on your own: https://medium.com/roblox-development/fixing-images-in-roblox-ui-to-look-good-2e0a7880b1ec

9-Slicing

9-Slicing is a technique used to make images scale without the edges losing quality and shape.

For example, you can turn a 100 x 100 circle image into a rectangle with rounded corners by slicing it through the middle so that each of the four corners of the slice is one quarter of the circle.

100x100 cicle

image

Image with and without 9-slicing

2020-05-31_16-09-21
2020-05-31_16-09-41

So how do you do it?

9-Slicing slices an image up into nine rectangles. Four of these, the corners, don’t change in size at all. The edges, four of them again, only stretch on the side they on, so a horizontal edge will stretch horizontally but not vertically. This leaves a final part - the center. This will probably make up the majority of your frame, and is recommended to be a plain color so it can stretch freely without us having to worry about details being distorted or pixelated.

Each image object has a property called ScaleType. Setting it to Slice will reveal a new property called SliceCenter. This revealed property is called a Rect (take note scripters), and has two Vector2s, one for each corner of a rectangle. X0 and Y0 is the top left corner, X1 and Y1 is the bottom right corner. This property uses pixels as its unit, so you will need to know the original dimensions of the image before you can slice it.

You can find a more in-depth tutorial here: How to use SliceCenter (Roblox's 9-Slice GUI Property)

Spritesheets

Often you may want to make a button that you hover over have a special effect or an image be animated. You don’t want to upload lots of images for one simple thing… so that’s where spritesheets come in.

Spritesheet example

image

A spritesheet is made up of different sections all in the same size. It is useful for holding lots of images inside a single image. So how do you implement this in Roblox?

All image objects have two properties: ImageRectSize and ImageRectOffset, which are both of the Rect value type (which short for rectangle, and contains two Vector2 values).

To define the size of each different sprite, you set ImageRectSize. To change which sprite the image is currently ‘viewing’, you use ImageRectOffset and set it to the location of the sprite (all in pixels of course).

Here’s an example:

I have two button images, one for the normal state, and one for when the button is hovered.

button_sheet
My 52x104 spritesheet

This is what the button and its properties look like in its normal state

Screenshot_246Screenshot_245
Default view

And this is what the button and its properties look like when hovered (note how ImageRectOffset is 52px on the X axis, aka looking at the second image on the spritesheet)

Screenshot_247Screenshot_248
Hover view


Padding

Padding (and margins) are something that a lot of people miss. Padding in design means a small empty space between the edges of elements. It’s kind of like visual zone with nothing in it, breathing room for the eyes. When a design doesn’t have padding, it looks kind of cut off and can feel like its overlapping with things that it isn’t.

You can see in this example that the edge of the text is touching the edge of the frame

Screenshot_209

Text

Most commonly this problem is found in objects with text, where the TextXAlignment or TextYAlignment is set to Left/Right or Up/Down. It doesn’t happen as much with Center because the text has even, empty space on each side.

Alignment Left

image

Alignment Center

image

Unfortunately, Roblox has not given us functionality to add padding inside a single TextLabel. So the only real solution to this is to create different objects for the background frame and the text.

You can do this by putting the TextLabel inside the frame, centering the label using 0.5, 0.5 AnchorPoint and 0.5, 0.5 Scale position, and giving it a smaller size than the background frame.

Without padding

image

With padding

image
image
image
(Scale Y is 4x smaller than Scale X because the frame is 4x longer than it is tall)

Other Elements

While padding is used often with text, it is also relevant in other places as well. Depending on your style, it is good to separate things like buttons and frames from the edges of the parent object.

You’ve got two options when it comes to padding: you can do it manually, or you can use the UIPadding object or other layout objects (they have Padding properties). I mostly use the UIPadding object, although I manually create padding frequently as well.

Example of both types of padding being used in a frame with two TextLabels and a button

image

UIPadding was used to create the padding between the edge of the frame and the edge of elements inside it. Manual padding was used to keep all 3 elements separate from each other.

UIPadding

I will first introduce UIPadding as it is the simplest. You put the object inside the parent of all the objects you want it applied to, and then set the PaddingLeft, PaddingRight, PaddingTop, and PaddingBottom properties to get padding applied at those locations (these values are UDims, so is in the form {Scale, Offset}).

You can see this in action using my example with 1/20th padding on each side

image
image

The cool thing about UIPadding is that when padding is applied, all child objects will be placed within the bounds of that padding, even if they have their size set to 1 in Scale.

In my example, all three of the elements have their horizontal size set to 1 in Scale, with no positioning information.

image

Note: The process is very similar for layout objects. However instead of defining padding for every corner, in layout objects you set the padding property either as a UDim2 (2 directions) or as a single UDim value (1 direction), where the direction is based on the layout. So if you’re using a UIListLayout, the padding is in the direction of the list.

Manual padding

Manual padding is essentially just manually resizing, repositioning and otherwise modifying elements so that they have space between them.

In the example above, each of the elements' vertical size and position was set so that there was empty space between each element. You can see that visualized here

image

There is also a slightly more complicated version used to replicate the behaviour the UIPadding has. For each element, you need to set the size to 1 - padding and the position to padding (or the center of the frame).

So for example, if you had a TextLabel inside a frame and you wanted 10px of padding on all sides, you could set the size to {1, -20}, {1, -20} and the position to {0, 10}, {0, 10}. Notice how the size is the full size of the parent, minus double the padding. The reason it is is double is because in this case I want to have padding on both the left and right sides. If we only wanted one side, we would only need to subtract 10 instead of 20.

Now for the position, there’s an easier way you can make the padding equal on all sides. By setting the AnchorPoint set 0.5, 0.5, you could set the position to {0.5, 0}, {0.5, 0} and then it will always be placed in the center. This method is useful if you’re changing the padding frequently as it means you don’t need to update the position when the size updates.


General Design

A few final things to follow when designing in general:

  • Try to have some contrast between elements - firstly not having good contrast would make things hard to see for players, and secondly people with poor eyesight or colourblindness would have a very hard time (imagine: grey text on a grey background).

  • Try to keep your UI from intruding upon the game - if you have sidebar buttons that cover a third of the screen, that’s not a very good use of space. The same goes for anything else that can appear on the screen. Note that a large UI can give a cartoony effect, but don’t do overdo it.

  • Consistency! Your UI should have the same style in all of its elements.
    If you’re going to use a free model or buy some scripted GUIs, it might be a good idea to edit the appearance of them so they fit the style of your game better. I’m not saying your UI should be uniform and only use a small number of colors (because that is boring and isn’t attractive to kids who like lots of bright colors), I’m just saying if possible you should pay some attention to how your UI works with itself.


Hopefully this was helpful :wink:

Don’t forget to check out UI Design Objects & Tips as well.

Good luck designing!

402 Likes
UI Design Objects & Tips
UI Resizing Based on Device Resolution
Interactive UIs
I want to start UI designing, but where do I start?
Loading Screens
Should I make my Inventory fully scale or fully offset?
Game Development Resources [MEGA THREAD]
Designing Advanced UI
Help, getting into UI design
Making a GUI perfect on any screen
Scale vs. Offset
Help, how can I make the GUI of my game available for mobile devices?
Need Help With Scaling UI
Exporting UI's from Photoshop & Importing them into Studio
Any idea on how to start UI designing?
Looking for help, tips and info
How to fix UI size
UI Design Resources For Beginners
How to make High Quality GUI's?
AnchorPoint & Making UIs Scaled on All Devices
Why is my UI so squished? I'm using Offset
Why is my UI so squished? I'm using Offset
Starting UI Design
9 - Slicing Use Cases
Need help on making loading screen
How do people make advanced GUIs/UIs?
Scale and Offset help
UI Scale problem
Need help with GUI Scaling
UI Scaling Issue
My UI Isn't appearing while the Visible Property is true
Cross platform UI if pretty hard
GUI Zoomed from different platforms?
[Advanced UI] Introduction to 2D Animations
Looking for help, tips and info
Gui resizing? What's the best way?
[currently unavailable] Experienced Scripter & UI Designer
Minimizing a GUI Issue
The image looks weird when it's in a tablet or a cell phone
UI Design Tutorials
How can I get into UI and what are the best free product s?
Can I get some advice on my Uis
What goes into making a appealing gui?
Thoughts on drop shadow on GUI
Messaging Service
Please leave some feedback on my shop UI
What's the best APP that can help you making a Good UI Design?
Locking a GUI into place

Wow. You really packed a lot of information in here. As a UI designer I’m impressed. There was a bit of information I did not even know. Kudos.

39 Likes

dang it eme i thought UI design was easy but this post makes me think the opposite how dare you make ui design look harder than it already is :triumph:

jk great tutorial

29 Likes

I love this, really dug into the details I wish I had in my tutorial which was more broad. :smiley:

I can’t tell you how much I hate not using margins and seeing UI without it!

8 Likes

Very nice tutorial. I’ll be sure to use this when I’m designing my GUIs. :grin:

6 Likes

Quite an excellent tutorial which went into detail features i was completely unaware of.

Well done.

7 Likes

Thanks for this.

UI designing is one thing I really want to get into since it can really *spice up a game.

* = Say it smoothly

9 Likes

Great job, packed with a ton of useful information and hints. Honestly, I really am glad to see that the user interface is slowly becoming of greater importance to Roblox developers! :smiley:

6 Likes

Great guide! I’ve always wanted to do what @Ultraw did with sprites while we were working on Restaurant Tycoon. :slight_smile:

3 Likes

Margin is not the same as padding, but other than that good tut

3 Likes

True but often this would sill require changes to optimize it for the platform.

Although I probably should have covered some of those other UI objects in the tutorial lol

3 Likes

Nice tutorial! I hope more and more new users understand and implement nice UI into their games. :octopus:

4 Likes

I think I already made a post with a joke about having you teach me about your ways of UI design. This tutorial is fabulous and has given me many great pointers and teachings about how to get started on good UI design.

Thank you very much for this guide. +1 like and bookmark. :grinning:

3 Likes

You’re the one who gave me the idea lol

Shoutout to colbert2677!

2 Likes

o-oh i didn’t know that

:hushed:

3 Likes

This is an awesome tutorial. Kudos on the spritesheets, had no idea how to implement them properly up until now.

5 Likes

I actually needed some info from this. Thanks!

5 Likes

How did I not know about Anchor Points :open_mouth: Good Tutorial!

6 Likes

Very Helpful If I ever want to get into UI designing, I will bookmark this.

5 Likes

I’m a bit late to the party here but thank you for writing this!

1 Like