AbsolutePosition not working properly

im trying to make a script that makes lines and connects them between skill tree nodes. The problem is the lines get misplaced and even the distance and angle calculations are incorrect for some reason. I tried to set the offset of the line(frame) directly to the button with

line.Position = UDim2.fromOffset(obj1.AbsolutePosition.X, obj1.AbsolutePosition.Y)

That would give it this weird offset, and even printing out the absolute position of the line and the button would give different results despite setting it directly equal to one another.

The nodes(buttons) have UIAspectRatioConstrains but even without it it still doesnt work. The anchor point of buttons is 0.5, 0.5, but even with 0, 0 it doesnt work. The parent container for lines is identical to parent container for buttons, but even parenting it to the same parent doesnt work. IgnoreGuiInset is on but it doesnt make a difference. What did somewhat work was

line.Position = obj1.Position

or parenting it to the button directly. This still makes the angle and size calculations fail though, even when I try doing them with scale. Parenting the line to the button doesnt work since I need the line to be rendered behind the button(and the calculations dont work).

Heres the current code:

local function makeLine(obj1: Frame, obj2: Frame)	
	
	local pos1 = obj1.AbsolutePosition --+ obj1.AbsoluteSize * obj1.AnchorPoint
	local pos2 = obj2.AbsolutePosition --+ obj2.AbsoluteSize * obj2.AnchorPoint
	
	local pos = (pos1 + pos2) / 2
	local addedPos = (obj1.Position + obj2.Position)
	local subtractedPos = (obj1.Position - obj2.Position)
	local scaleSize = Vector2.new(subtractedPos.X.Scale, subtractedPos.Y.Scale).Magnitude
	local offsetSize = Vector2.new(subtractedPos.X.Offset, subtractedPos.Y.Offset).Magnitude
	local midpoint = UDim2.new(addedPos.X.Scale / 2, addedPos.X.Offset / 2, addedPos.Y.Scale / 2, addedPos.Y.Offset / 2)
	local size = (pos1 - pos2).Magnitude --+ obj1.AbsoluteSize.Y
	local angle = math.deg(math.atan2(pos2.X - pos1.X, pos2.Y - pos1.Y))
	
	local line = Instance.new("Frame")
	--line.Size = UDim2.new(scaleSize, offsetSize, 0, 2)
	line.Size = UDim2.fromOffset(size, 2)
	line.BackgroundColor3 = Color3.new(1, 1, 1)
	line.BorderSizePixel = 0
	--line.Position = UDim2.new(0.5, pos.X, 0.5, pos.Y)
	line.Name = obj1.Name
	--line.Rotation = angle
	--line.Rotation = 45
	--line.AnchorPoint = Vector2.new(0.5, 0.5)
	obj1.AnchorPoint = Vector2.zero
	
	--[[line.Parent = obj1
	print(line.AbsolutePosition)
	local absPos = line.AbsolutePosition + line.AbsoluteSize * line.AnchorPoint
	local absSize = line.AbsoluteSize
	line.Size = UDim2.fromOffset(absSize.X, absSize.Y)
	line.Parent = obj1.Parent.Parent.Parent.Lines
	line.Position = UDim2.fromOffset(absPos.X, absPos.Y)
	print(line.AbsolutePosition)]]
	
	--line.Position = UDim2.fromOffset(pos1.X + line.AbsoluteSize.X / 2, pos1.Y + line.AbsoluteSize.Y / 2)
	--line.Position = UDim2.fromOffset(pos1.X, pos1.Y)
	line.Parent = obj1.Parent.Parent.Parent.Lines
	local offsetVector = (obj2.AbsolutePosition - obj1.AbsolutePosition).Unit * line.AbsoluteSize.X / 2
	--line.Position = midpoint
	line.Position = UDim2.fromOffset(obj1.AbsolutePosition.X, obj1.AbsolutePosition.Y)
	--line.Position = obj1.Position + UDim2.fromOffset(offsetVector.X, offsetVector.Y)
	--task.delay(0.1, print, obj1.AbsolutePosition, line.AbsolutePosition)
	--line.Parent = obj1
	
	return line
end

Ive commented out a lot of my other attempts.

1 Like
local pos1 = obj1.AbsolutePosition + obj1.AbsoluteSize / 2
local pos2 = obj2.AbsolutePosition + obj2.AbsoluteSize / 2

AbsolutePosition will always describe the position of the top left corner, no matter what AnchorPoint is. So adding half the size will always get you the center. I’d recommend setting AnchorPoint of the line to (0.5, 0.5) and setting the position to pos. As for the rotation, I never even knew that math.atan2 existed, and I use this custom function. Maybe it will work better.

local function getDegsOfLine(vector2:Vector2):number
	local output = 0
	local x, y = vector2.X, vector2.Y
	local slope = y / x
	if x < 0 and y < 0 then
		output += 180
	elseif x < 0 then
		output += 270
		x = math.abs(x)
		y = math.abs(y)
		slope = x / y
	elseif y < 0 then
		output += 90
		x = math.abs(x)
		y = math.abs(y)
		slope = x / y
	end

	output += math.deg(math.atan(slope))
	return output
end

line.Rotation = getDegsOfLine(pos1 - pos2)

And set the size to (pos1 - pos2).Magnitude

Yes Ive tried that but even just directly setting the absolute position of the button to the line makes it offset

Try subtracting the parent’s position from the AbsolutePosition

local parentPos1 = obj1.Parent.AbsolutePosition 
local parentPos2 = obj2.Parent.AbsolutePosition
local pos1 = obj1.AbsolutePosition + obj1.AbsoluteSize / 2 - parentPos1
local pos2 = obj2.AbsolutePosition + obj2.AbsoluteSize / 2 - parentPos2

I have. Parent position is 0, 0 in both cases. They are identical and Ive even tried parenting it to the same frame.

I just tested this script myself and it works fine:

local function makeLine(obj1: Frame, obj2: Frame)
	local parentPos1 = obj1.Parent.AbsolutePosition 
	local parentPos2 = obj2.Parent.AbsolutePosition
	local pos1 = obj1.AbsolutePosition + obj1.AbsoluteSize / 2 --- parentPos1
	local pos2 = obj2.AbsolutePosition + obj2.AbsoluteSize / 2 --- parentPos2
	local pos = (pos1 + pos2) / 2
	local size = (pos1 - pos2).Magnitude
	local function getDegsOfLine(vector2:Vector2):number
		local output = 0
		local x, y = vector2.X, vector2.Y
		local slope = y / x
		if x < 0 and y < 0 then
			output += 180
		elseif x < 0 then
			output += 270
			x = math.abs(x)
			y = math.abs(y)
			slope = x / y
		elseif y < 0 then
			output += 90
			x = math.abs(x)
			y = math.abs(y)
			slope = x / y
		end

		output += math.deg(math.atan(slope))
		return output
	end
	local angle = getDegsOfLine(pos1 - pos2)
	
	local line = Instance.new("Frame")
	line.Size = UDim2.fromOffset(size, 5)
	line.BackgroundColor3 = Color3.new(1, 1, 1)
	line.BorderSizePixel = 0
	line.Name = obj1.Name
	line.Rotation = angle
	line.Position = UDim2.fromOffset(pos.X,pos.Y)
	line.AnchorPoint = Vector2.new(.5,.5)
	line.Parent = game.StarterGui.Other

	return line
end

It seems like subtracting the parent’s position messes it up
EDIT: nevermind, you just need to subtract the position of the line’s parent, but it doesn’t matter in your case if the positions of the parents are the same.

Here’s what the bottom of the function should look like when the parent’s position isn’t (0, 0):

	local function getParentPos(object)
		local output
		local parent = object.Parent
		if parent:IsA("GuiObject") then
			output = parent.AbsolutePosition
		elseif parent:IsA("Folder") then
			output = getParentPos(parent)
		else
			output = Vector2.new(0,0)
		end

		return output
	end

	line.Parent = -- whatever you want
	local parentPos = getParentPos(line)
	line.Position = UDim2.fromOffset(pos.X - parentPos.X,pos.Y - parentPos.Y)
	line.AnchorPoint = Vector2.new(.5,.5)

Never mind. Turns out I was doing it on the server instead of the client. I transfered the calculations on the client and it works fine. Thanks anyway.

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