Rotation between 2 GUI objects

Hi. I’m trying to connect a line between two UI objects, but it doesn’t work as intended:


Here’s my code:

local A, B = script.Parent:WaitForChild("A"), script.Parent:WaitForChild("B");

local function createLine(a, b)
	local line = Instance.new("Frame")
	line.Name = "Line"
	line.BorderSizePixel = 0
	local UICorner = Instance.new("UICorner")
	UICorner.CornerRadius = UDim.new(0.02, 0)
	UICorner.Parent = line
	game:GetService("RunService").RenderStepped:Connect(function()
		local distanceX, distanceY = math.abs(a.Position.X.Scale - b.Position.X.Scale), math.abs(a.Position.Y.Scale - b.Position.Y.Scale);
		line.Size = UDim2.fromScale(distanceX, 0.02)
		line.Parent = script.Parent
		line.AnchorPoint = Vector2.new(0.5, 0.5)
		local X = b.Position.X.Scale - a.Position.X.Scale
		local Y = b.Position.Y.Scale - a.Position.Y.Scale
		line.Rotation = math.deg(math.atan2(Y, X))
		line.Position = a.Position + UDim2.fromScale(distanceX/2, distanceY/2)
	end)
end;

createLine(A, B)

Thanks for any help :slight_smile:

I believe the problem is that you’re using scale size and position, when you should be using AbsoluteSize and AbsolutePosition to get the middle of the frame, this is the result I got when I used AbsolutePosition and AbsoluteSize and changed some parts of your code


Code:

function positionLine(a,b,line)
	local distanceX, distanceY = a.AbsolutePosition.X-b.AbsolutePosition.X, a.AbsolutePosition.Y - b.AbsolutePosition.Y
	local AX,AY = math.abs(distanceX),math.abs(distanceY)
	line.Position = UDim2.new(0,b.AbsolutePosition.X+distanceX/2+a.AbsoluteSize.x/2,0,b.AbsolutePosition.Y+distanceY/2+a.AbsoluteSize.y/2)	
	line.Size = UDim2.new(0,AX/2+b.AbsoluteSize.x + AY/2+b.AbsoluteSize.y/2,.02,0)
	local X,Y = b.AbsolutePosition.X - a.AbsolutePosition.X, b.AbsolutePosition.Y - a.AbsolutePosition.Y

	line.Rotation = math.deg(math.atan2(Y, X))

end

another thing I did was put the line in a table and positioned the line in a RenderStepped outside the function

 lines[line] = {a,b}

game:GetService("RunService").RenderStepped:Connect(function()
	for line,frames in pairs(lines) do
		positionLine(frames[1],frames[2],line)
	end
end)

Hope this helps!

2 Likes

Thank you so much for the reply! Much appreciated :smiley: Thank you for helping me!

I found a problem, whenever the distance is long, the line isn’t big enough to fit in the frames, here:


Code:

local A, B = script.Parent:WaitForChild("A"), script.Parent:WaitForChild("B");

function positionLine(a,b,line)
	
	local distanceX, distanceY = a.AbsolutePosition.X-b.AbsolutePosition.X, a.AbsolutePosition.Y - b.AbsolutePosition.Y
	
	local AX,AY = math.abs(distanceX),math.abs(distanceY)
	
	line.Position = UDim2.new(0,b.AbsolutePosition.X+distanceX/2+a.AbsoluteSize.x/2,0,b.AbsolutePosition.Y+distanceY/2+a.AbsoluteSize.y/2)
	
	line.Size = UDim2.new(0,AX/2+b.AbsoluteSize.x + AY/2+b.AbsoluteSize.y/2,.02,0)
	
	local X,Y = b.AbsolutePosition.X - a.AbsolutePosition.X, b.AbsolutePosition.Y - a.AbsolutePosition.Y

	line.Rotation = math.deg(math.atan2(Y, X))

end

local function createLine(a, b)
	local line = Instance.new("Frame")
	
	line.Name = "Line"
	
	line.BorderSizePixel = 0
	
	local UICorner = Instance.new("UICorner")
	
	UICorner.CornerRadius = UDim.new(0.02, 0)
	
	UICorner.Parent = line
	
	line.Parent = script.Parent
	
	line.AnchorPoint = Vector2.new(0.5, 0.5)
	
	game:GetService("RunService").RenderStepped:Connect(function()
		positionLine(a, b, line)
	end)
end;

createLine(A, B)

Sorry, but the only solution I can think of right now is to change the AX/2 to AX/1.7, that however makes the line go too far if its too close, so you could do this

function positionLine(a,b,line)
	local distanceX, distanceY = a.AbsolutePosition.X-b.AbsolutePosition.X, a.AbsolutePosition.Y - b.AbsolutePosition.Y
	local AX,AY = math.abs(distanceX),math.abs(distanceY)
	line.Position = UDim2.new(0,b.AbsolutePosition.X+distanceX/2+a.AbsoluteSize.x/2,0,b.AbsolutePosition.Y+distanceY/2+a.AbsoluteSize.y/2)	
	local sizeX = AX/1.7+b.AbsoluteSize.x + AY/1.7+b.AbsoluteSize.y
	if AX <= a.AbsoluteSize.X*2.2 then
		sizeX = sizeX/2
	end
	line.Size = UDim2.new(0,sizeX,.02,0)
	local X,Y = b.AbsolutePosition.X - a.AbsolutePosition.X, b.AbsolutePosition.Y - a.AbsolutePosition.Y

	line.Rotation = math.deg(math.atan2(Y, X))

end

I made this small module so I can easily draw the lines but the positioning is way off. I am using the exact code you used, just modified variable names.

Here is what happens when running it, and here is the code for the script calling the module.