This is a useful algorithm I was working on today that makes a circular menu, inspired by GTA
local module = {}
function module.arrangeButtons(frame, buttons)
local buttonscale = (0.05 * (#buttons /4))
local buttonSize = {0.3 - buttonscale, 0, 0.3 - buttonscale, 0}
local frameSize = frame.Size
local radius = .5 -- Assuming the frame is a square
local function calculatePosition(index, totalButtons)
local angleIncrement = math.pi * 2 / totalButtons
local angle = angleIncrement * index
local x = (radius * (math.cos(angle)*.5)) - (buttonSize[1]*.5)
local y = (radius * (math.sin(angle)*.5)) - (buttonSize[3]*.5)
return UDim2.new(x+.5, 0, y+.5, 0)
end
for i, button in ipairs(buttons) do
button.Position = calculatePosition(i - 1, #buttons)
button.Size = UDim2.new(unpack(buttonSize))
end
end
return module
Updated post with a Model with the example interface!
Code has been updated to not use math.floor() to calculate button scale.
(Interact_Example)[https://create.roblox.com/store/asset/18108623226/Interact]
20 Likes
Works good!, i like it, maybe you could try doing a similar one but with circles instead?, i need it for a emote wheel
2 Likes
The button shape is arbitrary in a GUI. You can change the properties of the text button or add a image label of a circle. This is the code I use to create an the interface for my implementation.
local arrange=require(game.ReplicatedStorage.GlobalSpells.Arrange).arrangeButtons
local interactions=require(game.ReplicatedStorage.GlobalSpells.ChatbotAlgorithm.Commands.Interactions).command
local function interactbuttons()
arrange(Player.PlayerGui.Interact.Interactions,Player.PlayerGui.Interact.Interactions:GetChildren())
end
local template=Player.PlayerGui.Interact.Interactions.Item:Clone()
local function buttonconnect()
for i,v in interactions do
local b=template:Clone()
b.ItemID.Value=i
b.Text=i
b.Parent=Player.PlayerGui.Interact.Interactions
local con,dis=nil,nil
con=b.MouseButton1Click:Connect(function()
interactbuttons()
remote:FireServer({Player.PlayerGui.Interact.Adornee.Parent,Player.Character},b.ItemID.Value)
--interact.command[apicall].Condition(str[1],str[2],player)
b.Visible=false
b:Destroy()b.Parent=nil
dis:Disconnect()
con:Disconnect()
end)
dis=b.AncestryChanged:Connect(function()
con:Disconnect()
dis:Disconnect()
end)
end
end
local function cleanup()
for i,v in Player.PlayerGui.Interact.Interactions:GetChildren() do
v:Destroy()
end
end
local function buildinteractions()
cleanup()
Player.PlayerGui.Interact.Adornee=Player.PlayerGui.TalkGui.NPCTarget.Value
buttonconnect()
interactbuttons()
end
I have an array of keys that determine the number of buttons, then I connect events to them and fire a signal to the server to execute the function there and call it locally.
Also I have updated the code to not use math.floor when calculating the button scale.
1 Like