Line Script Not Working Properly Due To Monitor Not Being Square

I’ve tried to make a Line Script that makes a line between two points.
The problem is that the line isn’t connecting properly to the Points and kind of just floating.
I cannot find any similar problem on the forum.

I’ve narrowed the problem down to that my monitor isn’t a square but rectangular, But a coordinate system is, How Would You Avoid This Problem?

Video:

This is the code i’ve been using:

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

local ScreenGui = script.Parent

local Line = ScreenGui:WaitForChild("Line")
local P1 = ScreenGui:WaitForChild("P1")
local P2 = ScreenGui:WaitForChild("P2")

local function UpdateLine()
	
	--// Values:
	local P1x = P1.Position.X.Scale
	local P1y = P1.Position.Y.Scale
	local P2x = P2.Position.X.Scale
	local P2y = P2.Position.Y.Scale
	
	--// Gets Orientation:
	local XSlope = P1x - P2x
	local YSlope = P1y - P2y
	local Slope = YSlope / XSlope
	
	local Angle = math.atan(Slope)
	Angle = math.deg(Angle)
	Angle += 90
	
	--// Gets Position:
	local MidPointX = P1x + P2x
	local MidPointY = P1y + P2y
	MidPointX /= 2
	MidPointY /= 2
	
	--// Gets Size
	local YDist = P2x - P1x
	local XDist = P2y - P1y
	YDist ^= 2
	XDist ^= 2
	local Dist = YDist + XDist
	Dist = math.sqrt(Dist)
	
	print(tostring(Angle), tostring(MidPointX) .. ";" .. tostring(MidPointY), Dist)
	Line.Rotation = Angle
	Line.Position = UDim2.fromScale(MidPointX, MidPointY)
	Line.Size = UDim2.new(0, 10, Dist, 0)
	
end
UpdateLine()

local function OffsetToScale(Offset)
	local ViewPortSize = workspace.Camera.ViewportSize
	
	local ScaleX = Offset.X / ViewPortSize.X
	local ScaleY = Offset.Y / ViewPortSize.Y
	local Scale = UDim2.fromScale(ScaleX, ScaleY)
	
	return Scale
end

local function UpdateInput(Body, input)
	
	local Position = input.Position
	local Scale = OffsetToScale(Position)
	Body.Position = Scale
	UpdateLine()
	
end


local function InputBegan(Body, Input)
	if Input.UserInputType ~= Enum.UserInputType.MouseButton1 and Input.UserInputType ~= Enum.UserInputType.Touch then return end
	
	
	local Connection = UserInputService.InputChanged:Connect(function(input)
		if input.UserInputType ~= Enum.UserInputType.MouseMovement and input.UserInputType ~= Enum.UserInputType.Touch then return end
		UpdateInput(Body, input)
		
	end)
	
	Input.Changed:Connect(function()
		if Input.UserInputState ~= Enum.UserInputState.End then return end
		
		Connection:Disconnect()
		
	end)
	
end

P1.InputBegan:Connect(function(Input)
	InputBegan(P1, Input)
end)

P2.InputBegan:Connect(function(Input)
	InputBegan(P2, Input)
end)
1 Like

You can use math.atan2(y2 - y1, x2 - x1) to get the angle in radians
If you’re having other issues with the line appearing in the wrong place, make sure that it’s anchorpoint is set to 0.5, 0.5

If none of the above work, I’d suspect that the issue has to do with you using scale instead of offset

Still gives me the exact same result, although I’ve noticed that it only works in the Y-axis, The midpoint also works perfectly, just the rotation and length that’s wrong. Could this be to any help?

Could it have to do with that a monitor is not a square?

I managed to do it. I made a separate script only using offset instead of scale.
The question still stands though, How Would You Do It With Scale?
I guess you would use some kind of function converting Offset to Scale but that’ll completely Obsolete.

The New Offset Code I Used:

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

local ScreenGui = script.Parent

local Line = ScreenGui:WaitForChild("Line")
local P1 = ScreenGui:WaitForChild("P1")
local P2 = ScreenGui:WaitForChild("P2")

local function UpdateLine()
	
	--// Values:
	local P1x = P1.Position.X.Offset
	local P1y = P1.Position.Y.Offset
	local P2x = P2.Position.X.Offset
	local P2y = P2.Position.Y.Offset
	
	--// Gets Orientation:
	
	local Angle = math.atan2(P2y - P1y, P2x - P1x)
	Angle = math.deg(Angle)
	Angle += 90
	
	--// Gets Position:
	local MidPointX = P1x + P2x
	local MidPointY = P1y + P2y
	MidPointX /= 2
	MidPointY /= 2
	
	--// Gets Size
	local YDist = P2x - P1x
	local XDist = P2y - P1y
	YDist ^= 2
	XDist ^= 2
	local Dist = YDist + XDist
	Dist = math.sqrt(Dist)
	
	print(tostring(Angle), Dist)
	
	Line.Position = UDim2.fromOffset(MidPointX, MidPointY)
	Line.Size = UDim2.new(0, 5, 0, Dist)
	Line.Rotation = Angle
	
end
UpdateLine()

local function UpdateInput(Body, input)
	
	local Position = input.Position
	Body.Position = UDim2.fromOffset(Position.X, Position.Y)
	UpdateLine()
	
end


local function InputBegan(Body, Input)
	if Input.UserInputType ~= Enum.UserInputType.MouseButton1 and Input.UserInputType ~= Enum.UserInputType.Touch then return end
	
	
	local Connection = UserInputService.InputChanged:Connect(function(input)
		if input.UserInputType ~= Enum.UserInputType.MouseMovement and input.UserInputType ~= Enum.UserInputType.Touch then return end
		UpdateInput(Body, input)
		
	end)
	
	Input.Changed:Connect(function()
		if Input.UserInputState ~= Enum.UserInputState.End then return end
		
		Connection:Disconnect()
		
	end)
	
end

P1.InputBegan:Connect(function(Input)

	InputBegan(P1, Input)
	
end)
P2.InputBegan:Connect(function(Input)

	InputBegan(P2, Input)
	
end)

I guess you would use some kind of function converting Offset to Scale but that’ll completely Obsolete.

local XScale = X / Camera.ViewportSize.X
local YScale = Y / Camera.ViewportSize.Y
2 Likes