I want to create an Osu-style circular UI event where a shrinking circle (Click frame) must be clicked exactly on the stroke of a larger circle (Area frame with UIStroke) to succeed. The click must happen strictly on the stroke of the Area frame, and it should not count as success if the click is either inside the center or outside the stroke. I have tried various tests but have not been able to achieve a functional result yet.
Example image: the green represents the area, and the black represents the shrinking area.
I found a way to do it, I’m not sure if it’s the best, but for anyone who wants to know, here it is:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TweenService = game:GetService("TweenService")
local Players = game:GetService("Players")
--------------------
--| Library |--
--------------------
local _L = require(ReplicatedStorage:WaitForChild("Core"):WaitForChild("Library"))
-------------------
--| Variables |--
-------------------
local Player = Players.LocalPlayer
local PlayerGui = Player:WaitForChild("PlayerGui")
local CatchGui = PlayerGui:WaitForChild("Gui"):WaitForChild("Catch")
local Tool = script.Parent
local Area = CatchGui:WaitForChild("Area")
local Click = CatchGui:WaitForChild("Click")
local strokeThickness = Area.UIStroke.Thickness
local areaSize = Area.Size.X.Scale * 400 --Size of frame: 400x400
local function calculateAreas()
local inRadius = areaSize / 2
local inArea = math.pi * inRadius^2 -- Internal area
local outRadius = (areaSize + 2 * strokeThickness) / 2
local outArea = math.pi * outRadius^2 -- External area with border
return inArea, outArea
end
Tool.Activated:Connect(function()
local ts = TweenService:Create(Click, TweenInfo.new(10, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut), { Size = UDim2.new(0, 0, 0, 0) })
ts:Play()
local inArea, outArea = calculateAreas()
while true do
local clickRadius = (Click.Size.X.Scale * 400) / 2
local clickArea = math.pi * clickRadius^2
local adjustedInArea = inArea - math.pi * (strokeThickness^2)
if (clickArea <= outArea) and (clickArea >= adjustedInArea) then
print("Inside")
else
print("Outside")
end
wait()
end
end)
If anyone has a better alternative, feel free to leave it here so we can know.