Movement within a Circle

Trying to make white circle move inside of black circle

Current code

	local delta = uis:GetMouseDelta()
	
	local centerPosition = UDim2ToVector2(main.Position)
	
	local y = math.clamp(delta.Y,-10,10)
	local x = math.clamp(delta.X,-10,10)
	
	local udX = math.clamp(circle.Position.X.Scale + x/100,0,1)
	local udY = math.clamp(circle.Position.Y.Scale + y/100,0,1)
	
	--circle.Position = UDim2.fromScale(udX,udY)
	
	local a = UDim2ToVector2(UDim2.fromScale(udX,udY))
	local b = UDim2ToVector2(UDim2.fromScale(0.5,0.5))
	
	local distance = (UDim2ToVector2(UDim2.fromScale(0.5,0.5)) - a).Magnitude
	
	local acos = (a.X * b.X + a.Y * b.Y) / (math.sqrt(a.X*a.X + a.Y*a.Y) * math.sqrt(b.X*b.X + b.Y*b.Y))
	
	
	print(acos)
	
	local nextPos = UDim2.fromScale(0.5,0.5) + UDim2.fromScale(math.sin(acos) * distance, math.cos(acos) * distance)
	circle.Position = nextPos
1 Like

Could you give us the code? I think you’ll have to manually set some boundaries for the circle. And If it is a ImageLabel, try making it a Frame with a UiCorner.

UIcorner does not change the frame’s hitbox so that would not work.

You could get the direction and multiply it by the distance.

It sounds good, but im so tired doing this, can i get hint?

I don’t really know what the position of the circle depends on. Does it depend on the rotation of the player’s camera

No it doesnt, im using Mouse Delta
Also circle AnchorPoint = Vector2.new(0.5,0.5)

In a circle, all points on its line are at the same distance as the circle so just clamp it so that the position does not go further than the distance between the circle end and centre.

Basically, add x and y and see if it goes further and if it does reduce both.
Hope this helps.

First, don’t limit the circles position at all.
Second,

(MiddlePosition - CirclePosition).Unit -- Both positions are Vector2s. Remember not to limit the circle position

Lastly, multiply the unit by Mouse Delta or a different number

1 Like

How do i convert UDim2 to Vector2?

Just do:

local ConvertedToVector = Vector2.new(YourUDimOffsetX, YourUDimOffsetY)

(works only if you are using offset to position the circle)

I would recommend setting the position to 0.5,0.5 (with zero offset) and then offsetting the circle to the correct position.

i have problem

local function UDim2ToVector2(UDim2)
	return Vector2.new(UDim2.X.Offset, UDim2.Y.Offset)
end

local function OnUpdate()
	local delta = uis:GetMouseDelta()
	
	local deltay = math.clamp(delta.Y,-10,10)
	local deltax = math.clamp(delta.X,-10,10)
	
	local X = circle.Position.X.Offset + deltax
	local Y = circle.Position.Y.Offset + deltay
	
	local nextPos = UDim2.fromOffset(X,Y)
	local nextVector = UDim2ToVector2(nextPos)
	
	local mag = (centerVector - nextVector).Magnitude
	local unit = (centerVector - nextVector).Unit
	
	print(mag)
	
	circle.Position = UDim2.new(0.5, unit * mag, 0.5, unit * mag)
	
end

local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")

local BlackCircle = script.Parent:WaitForChild("BlackCircle")
local WhiteCircle = BlackCircle:WaitForChild("WhiteCircle")

local function calculateWhiteCircleOffset(whiteCircle, blackCircle)
	local mouseDelta = UserInputService:GetMouseDelta()
	
	-- Vector2.new().Unit returns {NAN, NAN} and if we set a frame's position to
	-- {NAN, NAN} then it'll disappear
	if mouseDelta == Vector2.new() then
		return Vector2.new()
	end
	
	-- value between 0 and 1
	local distFromOriginAlpha = math.min(
		mouseDelta.Magnitude / Vector2.new(10, 10).Magnitude,
		Vector2.new(10, 10).Magnitude,
	)

	local whiteCircleRadius = whiteCircle.AbsoluteSize.X * 0.5
	local blackCircleRadius = blackCircle.AbsoluteSize.X * 0.5

	-- we're subtracting the white circle radius from the black circle radius
	-- so that the white circle doesn't pop out from the black circle at high
	-- mouse deltas
	local maxDistFromOrigin = blackCircleRadius - whiteCircleRadius
	local offset = mouseDelta.Unit * maxDistFromOrigin * distFromOriginAlpha

	return offset
end

RunService.Heartbeat:Connect(function()
	local whiteOffset = calculateWhiteCircleOffset(WhiteCircle, BlackCircle)
	WhiteCircle.Position = UDim2.new(0.5, whiteOffset.X, 0.5, whiteOffset.Y)
end)

here is my attempt at solving your problem.
you may also want to do some smoothing so it isn’t jerky

1 Like

This is my code that I made for my custom joystick and it works perfectly.

local MaxPosX, MaxPosY = BackgroundFrame.AbsoluteSize.X / 2, BackgroundFrame.AbsoluteSize.Y/ 2
--// BackgroundFrame is the dark background, direction is the same as unit in your script
Circle.Position = UDim2.new(
	0.5,
	(direction * math.min(magnitude, MaxPosX)).X,
	0.5,
	(direction * math.min(magnitude, MaxPosY)).Y
)
2 Likes
local direction = (MouseDelta).Unit
local magnitude = (MouseDelta).Magnitude -- The distance of MouseDelta from (0,0)

Yeah it seems like it works, but how could i remove “Spring” effect

This happens

NEVERMIND GUYS, THANK YOU SO MUCH.
Actually fixed problem by mixing your versions in to one, thank you again.

1 Like

Clamping in roblox is based around a Box shape, so if you try to clamp that circle in the way you said, it just becomes a box