UI Positioning Question


#1

I’ve just started out with UI designing and scripting them but I’ve come across a problem. When I edit my UI on Studio it comes out perfectly centered, but when I join the game, all my UIs become wonky. I was reading other post about AnchorPoints and they help me fix my problem, but how do they work?

I don’t want to keep searching everything up to find out which AnchorPoint to use to position my UIs because that will be a waste of time.

Also is there another way to position UIs better so it fits all screen sizes? I’ve heard of people using scripts but what do you do?


#2

To easily centre a GUI element, you should use GuiObject.AnchorPoint, which acts as the “origin point” of the element. If you assign this to Vector2.new(0.5, 0.5), the origin will be in the centre.

You can then assign its position to Udim2.new(0.5, 0, 0.5, 0) to have the element positioned exactly halfway along the X and Y axis of its parent element, or in the middle.

This works with all screen sizes because we’re positioning the element using scale rather than offset; where offset describes absolute pixels, the scale of an element is relative to its parent element.

You can learn more about GUIs here.


#3

Personally, I use UIAspectRatioConstraints to make sure they are scaled properly on all devices.

Here are some tips:

  • Use UI Constraints
    Instead of using offset for a square button, you can just insert a UIAspectRatioConstraint inside that button and make the size to scaled and it will keep the ratios fixed to a certain size for all devices. Let’s say you had an ImageButton sized {0, 100, 0, 100}, you would insert a UIAspectRatioConstraint and then change the size to something like (0.25, 0, 0.25, 0). There are also a ton of other UI Constraints such as the UIGridLayout which makes life much easier, consider checking them out on the wiki.

  • Use AnchorPoints to position something to the center of the screen.
    If you want to center something to the center of the screen, AnchorPoints may come in handy. You can set the AnchorPoint to {0.5, 0.5} which positions the AnchorPoint in the center of the GuiObject, then you set the position of the GuiObject to {0.5, 0, 0.5, 0} which makes it perfectly positioned in the center of the screen and automatically adjusts for any changes in the GuiObject size. You can also use it to make something positioned off the side of the screen by setting the AnchorPoint to {1, 0.5} and then setting the position to {1, 0, 0.5, 0} or any other respective positions.

I hope this helps! If you have any other questions feel free to contact me :slight_smile:


#4

Along side with UIAspectRatioConstraints, I would also look into using UISizeConstraint and UITextSizeConstraint to clamp the size your interface elements so on different devices things won’t look too small or too big. Especially comparing Xbox with Mobile devices.


#5

How do I tackle the UISizeConstraint? The default is infinite max size, but how to I make the my UIs smaller on mobile but stay the same size on PC/Xbox? I’m having a problem where the sizes of my UIs are too large on mobile, but when I make the SizeConstraint smaller, it makes my UI smaller for all screens.


#6

If you’re unable to come up with something to suit your specific needs using the constraint instances, you could check whether the user is using a mobile device by checking that there is no keyboard, and a touchscreen is enabled with:

if (not UserInputService.KeyboardEnabled) and UserInputService.TouchEnabled then
    -- mobile user, give different gui
end

and then offer a GUI designed specifically for that device. Or you could base it on the size of their game window by taking a look at their camera’s ViewportSize.

local Size = workspace.CurrentCamera.ViewportSize
if Size.X < 800 and Size.Y < 600 then
    -- mobile user, give different gui
end

#7

A simple solution to this would be to use scale to size your GUI, but can often result in stretched elements that look ugly. You can counteract this to a certain degree with 9-slicing.

If you want to maintain the exact aspect ratio of your GUI, I recommend using scale for the root (greatest ancestor) GUI, along with an UIAspectRatioConstraint. This will maintain your GUI’s aspect ratio (and therefor aesthetic) while scaling with any screen size. It’s what I personally use for my GUI.

Good luck! :wink:


#8

Adding onto what @JoshRBX said, if you do decide to go the route of platform specific designs, here’s a useful function to get the players current platform.

function GetPlayerPlatform()
	local Platform = nil
	if UserInputService.TouchEnabled then
		local ScreenSize = workspace.CurrentCamera.ViewportSize
		if ScreenSize.Y > 500 then		
			Platform = 4 -- Tablet
		else
			Platform = 3 -- Phone
		end
	else
		if not UserInputService.KeyboardEnabled then
			if UserInputService:GetGamepadConnected(Enum.UserInputType.Gamepad1) then
				Platform = 2 -- Xbox
			end
		else
			Platform = 1 -- PC
		end
	end	
	return Platform
end

print(GetPlayerPlatform())

#9

Going off of what various others have said, I personally use AnchorPoints and UI Constraints, in addition to specific functions to accommodate screen sizes.


#10

I use combinations of scale, AnchorPoints, and UIAspectRatioConstraints. However I’d suggest that if you are taking mobile players seriously, you should create a different layout of the UI and only enable it for mobile users. This makes it a lot more optimized as even though the original would still fit, it may not be a great layout for mobile.


#11

I think a better way of detecting Xbox would be GuiService:IsTenFootInterface(), correct me if I’m wrong tho

Edit: don’t use it to detect input types! See below


#12

There is no proper way of detecting platform; the only real functionality that we’re provided with is detecting the input device of the client (which, as you probably know, does not determine the actual platform). This is the only information that the developer necessarily needs to know about the player’s device. Determining the GUI elements that you use should be based off screen size rather than device. Likewise, determining whether to, say, visually display the “A” button on a controller or an “E” button on a keyboard to interact with an object, should be based on the input device.

I recommend using UserInputService:GetLastInputType to detect the correct input device to account for.


#13

I was more talking about detecting platforms as opposed to input types, but updated my post anyway to make it clearer


#14

That’s what I’m saying. We shouldn’t really be focusing on platform in the first place, rather input device and screen size. This is why Roblox don’t intentionally provide us with any way to do this.

Just my two cents. :wink:


#15

That makes sense, thanks for the information. :slight_smile: