How do I use AddConstraintFunction to constrain a UIDragDetector within a circle

I’m trying to use the UIDragDetector AddConstraintFunction function to prevent the red circle joystick from moving outside of the bounds.
So far I managed to find the constrained position (green square in video) but I’m not sure how to apply it to the AddConstraintFunction

I didn’t set the proposedMotion in this code for testing purposes, but I have tried returning different values in my constrainToCircle function.

code:

local dragDetector = script.Parent
local joystickGui = dragDetector.Parent
local bounds = joystickGui.Parent
local radius = bounds.AbsoluteSize.Y * 0.5
local center = nil
local originalPos = nil
local startPartPosition = nil

dragDetector.DragStart:Connect(function()
	originalPos = dragDetector.DragUDim2
	startPartPosition = joystickGui.Position
	
end)

dragDetector.DragEnd:Connect(function()
	dragDetector.DragUDim2 = originalPos
end)

local function createTestFrame(absolutePosition, rgb)
	local testFrame = Instance.new("Frame")
	testFrame.Position = UDim2.new(0, absolutePosition.X, 0, absolutePosition.Y)
	testFrame.Size = UDim2.new(0,5,0,5)
	testFrame.BackgroundColor3 = rgb
	testFrame.Parent = bounds.Parent.Parent
	return testFrame
end

local testFrame1, testFrame2 = nil, nil

local function constrainToCircle(proposedMotion, proposedRotation)
	if testFrame1 and testFrame2 then
		testFrame1:Destroy()
		testFrame2:Destroy()
		testFrame1, testFrame2 = nil, nil
	end
	
	local relativeMotion = (dragDetector.DragUDim2 - bounds.Position)
	
	center = bounds.AbsolutePosition + Vector2.new(radius, radius)
	local joystickPosition = joystickGui.AbsolutePosition + Vector2.new((joystickGui.AbsoluteSize.X * 0.5), (joystickGui.AbsoluteSize.Y * 0.5))
	
	local absoluteMotion = (center - joystickPosition)

	local fixedMotion = absoluteMotion.Unit * math.min(absoluteMotion.Magnitude, radius)
	
	--test frames for debugging
	testFrame1 = createTestFrame(bounds.AbsolutePosition + Vector2.new(radius, radius), Color3.fromRGB(255,0,0))

	local direction = (joystickPosition - center).Unit
	if absoluteMotion.Magnitude > radius then
		local newPosition = (center + direction * radius)
		testFrame2 = createTestFrame(newPosition, Color3.fromRGB(0,255,0))
		local newPosToUDIM2 = UDim2.fromOffset(newPosition.X, newPosition.Y)
		return proposedMotion, proposedRotation
	else
		return proposedMotion, proposedRotation
	end
end

dragDetector:AddConstraintFunction(1, constrainToCircle)

JoystickUIDragDetector.rbxl (60.2 KB)

1 Like

Changes to UIDragDetector:
DragRelativeRelative


JoystickUIDragDetector.rbxl (60,3 KB)

1 Like

Wow. That’s an embarrassingly simple fix and I probably overcomplicated the code :sweat_smile: Thanks! I hadn’t considered that the settings of the dragdetector were a part of the problem…

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.