How to choose a random position in a certain range on a Gui

I am trying to make a button that sets an image label’s position in a random position inside a frame. I can’t find a way how to do this with the image staying in the radius of the frame size.

This is the frame and the image label (the circle in the middle)
image

I can’t seem to find a way how to accomplish this and would really appreciate your help.

3 Likes

Use the math.random function and the bounds of the X size and Y size.

Set two variables one with say math.random(0, someFrame.Size.X) and another for the Y size. That should work if I am not wrong.

Didn’t work since math.random can’t take a Udim value. Thanks for the help though

Specify the X.offset value in the Udim2.

As @tannnxr said, you should use math.random.

The above line would not work as we must remember that there exists Scale and Offset. UDim2 values can not be passed as numbers since they have those two properties. Rather than Frame.Size, I will use Frame.AbsoluteSize in this example.
Try this revised script:

-- The Frame and ImageLabel variables should be changed to their
-- respective instance paths.
local Frame = script.Parent
local ImageLabel = Frame.ImageLabel

-- Border radius is simply the pixel count that should be always be
-- between the circle and the frame border.
local BorderRadius = 3

-- Size is the size of the circle, and assumes that it is perfectly
-- square, meaning the X size is equal to the Y size.
local Size = ImageLabel.AbsoluteSize.X

-- XSize and YSize find the size range for the circle to be located
-- within. This prevents it from going off the border.
local XSize = Frame.AbsoluteSize.X - BorderRadius * 2 - Size
local YSize = Frame.AbsoluteSize.Y - BorderRadius * 2 - Size

-- XPosition and YPosition find a random value (0 - 1) to place the
-- circle at.
local XPosition = (math.random() * XSize) / XSize
local YPosition = (math.random() * YSize) / YSize

-- Sets the image label to the correct position, with the border radius
-- kept in consideration.
ImageLabel.Position = UDim2.new(XPosition,BorderRadius,YPosition,BorderRadius)

I commented and tried to best explain each line of the code. I hope this explanation makes sense to you. If you have any question let me know. Also, if you find any errors that I have made, please let me know so I can correct them to best help you.

Good luck! :grinning_face_with_smiling_eyes:

  • Galactiq
1 Like

Works perfectly, thanks so much

1 Like

I did run into a flaw though:

The circle goes off of the frame some times
image

I wrote a new script in my own studio to test it out and reworked certain parts of it. Additions include fixing the issue you stated above and an implemented way to have images that aren’t necessarily square.

Instance Hierarchy: (can be changed)
image

The new script I wrote creates a new image in a random location whenever you click a button. The only new requirement is that the AnchorPoint of the image is set to 0.5, 0.5.

Script:

-- Variables

local UI = script.Parent
local Frame = UI.Frame
local Button = Frame.TextButton
local ImageLabel = script.ImageLabel

-- Settings

local BorderRadius = 3 -- Number of pixels circle can be (at minimum) from frame border

-- Main Function

local function RandomLocation()
	local New = ImageLabel:Clone() -- Create new frame
	
	local NewSizeX = New.AbsoluteSize.X -- X size of new image label
	local NewSizeY = New.AbsoluteSize.Y -- Y size of new image label
	local FrameSizeX = Frame.AbsoluteSize.X -- X size of frame
	local FrameSizeY = Frame.AbsoluteSize.Y -- Y size of frame
	
	local RangeX = FrameSizeX - BorderRadius * 2 - NewSizeX -- Range of possible values for the X position
	local RangeY = FrameSizeY - BorderRadius * 2 - NewSizeY -- Range of possible values for the Y position
	
	local PositionX = (math.random(RangeX) + BorderRadius + NewSizeX / 2) / FrameSizeX -- X scale position of image
	local PositionY = (math.random(RangeY) + BorderRadius + NewSizeY / 2) / FrameSizeY -- Y scale position of image
	
	New.Position = UDim2.new(PositionX,0,PositionY,0) -- Positions image
	New.Parent = Frame -- Parent image to frame
end

-- Button Event

Button.MouseButton1Click:Connect(RandomLocation)

Testing Result: (clicked over 600 times)
image

6 Likes

Updated my code and it almost seems like it is off a tiny bit:
image
More on the bottom right of the screen than the top left.

Code
local Players = game:GetService("Players")

local player = Players.LocalPlayer

-- Fetch the thumbnail
local userId = player.UserId
local thumbType = Enum.ThumbnailType.HeadShot
local thumbSize = Enum.ThumbnailSize.Size60x60
local content, isReady = Players:GetUserThumbnailAsync(userId, thumbType, thumbSize)

local UI = script.Parent
local Frame = UI.Option1
local Button = Frame.Vote
local ImageLabel = script.ImageLabel

-- Settings

local BorderRadius = 3 -- Number of pixels circle can be (at minimum) from frame border

-- Main Function

local function RandomLocation()
	local New = ImageLabel:Clone() -- Create new frame
	New.Image = content
	local NewSizeX = New.AbsoluteSize.X -- X size of new image label
	local NewSizeY = New.AbsoluteSize.Y -- Y size of new image label
	local FrameSizeX = Frame.AbsoluteSize.X -- X size of frame
	local FrameSizeY = Frame.AbsoluteSize.Y -- Y size of frame

	local RangeX = FrameSizeX - BorderRadius * 2 - NewSizeX -- Range of possible values for the X position
	local RangeY = FrameSizeY - BorderRadius * 2 - NewSizeY -- Range of possible values for the Y position

	local PositionX = (math.random(RangeX) + BorderRadius + NewSizeX / 2) / FrameSizeX -- X scale position of image
	local PositionY = (math.random(RangeY) + BorderRadius + NewSizeY / 2) / FrameSizeY -- Y scale position of image

	New.Position = UDim2.new(PositionX,0,PositionY,0) -- Positions image
	New.Parent = Frame -- Parent image to frame
end

-- Button Event

Button.MouseButton1Click:Connect(RandomLocation)

Fixed: Forgot about changing the anchor point . Thank you so so much for your help :slight_smile:

1 Like