I want to have an image UI per player in the server, and I want those images to all align in a circle around the middle of the screen. How can I do this?
Take this code and use it if you want, but I will go ahead and explain the math behind it below: (Inside a local script set within a screengui which holds all the frames we are arranging)
local screenGui = script.Parent local children = screenGui:GetChildren() local frames = {} local radius = 200 -- measured in pixels local mid = UDim2.new(0, screenGui.AbsoluteSize.X/2, 0, screenGui.AbsoluteSize.Y/2) --Make sure all are frames for i, v in pairs(children) do if v:IsA('Frame') then frames[#frames + 1] = v end end --Setting Positions Of Frames for i, v in pairs(frames) do v.Position = mid + UDim2.new(0, math.sin(2*math.pi*(i-1)/#frames)*radius - v.AbsoluteSize.X/2, 0, math.cos(2*math.pi*(i-1)/#frames)*radius - v.AbsoluteSize.Y/2) end
Math:
We start with the midpoint:
local mid = UDim2.new(0, screenGui.AbsoluteSize.X/2, 0, screenGui.AbsoluteSize.Y/2)
screenGui.AbsoluteSize is a vector2 so we have to set it up this way in order to add it later.
We then create another UDim2 value to add to the midpoint. Let's break it down.
Right from basics,
math.sin and math.cos take values in Radians (Like degrees except 360 degrees is 2*pi, therefore 90 degrees is pi/2, etc.). I won't show where radians come from but there is a reason we choose this value.
We then take some ideas from math, specifically complex roots of unity. Look into this if you need a detailed explanation. The main idea is that for complex numbers of the form z = CosA + iSinA centred around a point (X, Y), which we define to be the centre of the screen using our 'mid' variable, starting from the Y axis, as per the image you provided, the position of the nth point in a cartesian co-ordinate system, is given by (sin((n-1)*2*pi/m) + X, cos((n-1)*2*pi/m) + Y), where m is the number of complex numbers we have. We don't need to worry too much about exactly what a complex number is, but you should at least try to understand the math we are using here. These points now lay on a circle around our centre (X, Y) of radius 1. We can just multiply the vertical and horizontal components of our specified points by our desired radius to change the radius of the circle these points all lie on.
If you've followed this far, congrats! This isn't easy math by any means, but it's necessary. Now onto our last piece of the puzzle!
Roblox takes the point we provide and alligns the top left corner of our gui element with that point. How do we get back to the centre? We simply move left by half the width of our frame and up by half the height of our frame. This result is the same as subtracting half of the absolute size of our frame.
With all of that math put together, we get, at last:
v.Position = mid + UDim2.new(0, math.sin(2*math.pi*(i-1)/#frames)*radius - v.AbsoluteSize.X/2, 0, math.cos(2*math.pi*(i-1)/#frames)*radius - v.AbsoluteSize.Y/2)