Hey devs! Recently, I needed to connect two GUI objects with a line, but I ran into some challenges.
There was unfortunately not enough ressources and the forums were not clear enough and that will help my case. However, I managed to figure it out and just wanted to share how I solved it. I hope this helps anyone who might be facing a similar issue!
In this forum, I’ll be going over how to:
Connect 2 GUI Objects with a frame line
Connect a frame with the mouse location using a frame line
However, when it comes to making these 2,
it may be a bit tricky because its important we take in consideration the the 'IgnoreGuiInset'
property in the screenGUI.
You can learn more about IgnoreGuiInset and :GetGuiInset() here.
Anyways, Here’s the function that I made for Connect 2 GUI Objects with a frame line:
local gui_service = game:GetService("GuiService")
-- Dont mind the function name, it works with any UI Object, not just frames
local function Connect_frames(F1, F2, Frame)
local guiInset = gui_service:GetGuiInset()
local screen_ui :ScreenGui = F1:FindFirstAncestorWhichIsA("ScreenGui")
local inset_enabled = screen_ui.IgnoreGuiInset
local F1Pos = F1.AbsolutePosition
local F1Size = F1.AbsoluteSize
-- Calculate the center of the first frame
local F1Center = F1Pos + (F1Size / 2)
local F2Pos = F2.AbsolutePosition
local F2Size = F2.AbsoluteSize
-- Calculate the center of the second frame
local F2Center = F2Pos + (F2Size / 2)
-- Take the IgnoreGuiInset in consideration
F1Center = F1Center + (inset_enabled and guiInset or Vector2.zero)
F2Center = F2Center + (inset_enabled and guiInset or Vector2.zero)
-- Calculate the difference in X and Y coordinates between the centers of F1 and F2
local Distance = Vector2.new(F1Center.X, F1Center.Y) - Vector2.new(F2Center.X, F2Center.Y)
local Difference = F1Center - F2Center
-- Calculate the midpoint between the centers of F1 and F2
local CenterPosition = (F2Center + F1Center) / 2
-- The angle between F1 and F2
Frame.Rotation = math.deg(math.atan2(Difference.Y, Difference.X))
-- Position the frame at the midpoint between F1 and F2
Frame.Position = UDim2.fromOffset(CenterPosition.X, CenterPosition.Y)
-- Set the size of the frame to span the distance between F1 and F2
Frame.Size = UDim2.fromOffset(Distance.Magnitude, 1)
end
And here’s how it should be used:
local F1 = ... -- Your frame or label or whatever
local F2 = ...
local Frame = Instance.new("Frame", Parent) -- the connecting frame
Frame.AnchorPoint = Vector2.new(0.5, 0.5)
Connect_frames(F1, F2, Frame)
Here is a video showcasing how Connect_frames
works:
However, when it comes to Connect a frame with the mouse location using a frame line
the state of IgnoreGuiInset affects both the positions of the mouse location and the frame,
I managed to find a way to make the mouse and the frame connect correctly no matter the state of that property, here’s the script:
local uis = game:GetService("UserInputService")
local gui_service = game:GetService("GuiService")
local function Connect_frame_mouse(F1, Frame)
-- Get the current mouse location on the screen
local mouse_location = uis:GetMouseLocation()
-- Get the GUI inset to adjust for any screen GUI offsets
local guiInset = gui_service:GetGuiInset()
local screen_ui :ScreenGui = F1:FindFirstAncestorWhichIsA("ScreenGui")
local inset_enabled = screen_ui.IgnoreGuiInset
local F1Pos = F1.AbsolutePosition
local F1Size = F1.AbsoluteSize
local F1Center = F1Pos + (F1Size / 2)
-- Adjust the mouse position for GUI insets to get the correct position on the screen
F1Center = F1Center + (inset_enabled and guiInset or Vector2.zero)
local mousePos = mouse_location - (not inset_enabled and guiInset or Vector2.zero)
local Difference = F1Center - mousePos
local Distance = Vector2.new(F1Center.X, F1Center.Y) - Vector2.new(mousePos.X, mousePos.Y)
-- Calculate the midpoint between the frame center and the mouse position
local CenterPosition = (mousePos + F1Center) / 2
-- Set the rotation of the frame to match the angle between the frame center and the mouse
Frame.Rotation = math.deg(math.atan2(Difference.Y, Difference.X))
Frame.Position = UDim2.fromOffset(CenterPosition.X, CenterPosition.Y)
Frame.Size = UDim2.fromOffset(Distance.Magnitude, 20)
end
And here’s how it’s setup:
local uis = game:GetService("UserInputService")
local gui_service = game:GetService("GuiService")
local F1 = ... -- Your frame or label or whatever
local Frame = Instance.new("Frame", Parent) -- the connecting frame
Frame.AnchorPoint = Vector2.new(0.5, 0.5)
Connect_frame_mouse(F1, Frame)
Here is a video showcasing how Connect_frame_mouse
works:
And those are pretty much all the use cases
for connecting 2 GUI objects, you can do it with anything
'TextLabels', 'TextButtons', etc...
And of course you can change the connecting line visually:
local Frame = Instance.new("Frame", Parent) -- the connecting frame
Frame.AnchorPoint = Vector2.new(0.5, 0.5)
Frame.BackgroundColor = ... -- Any color you wish!
As for the size of the line, you just need to do the following inside the function:
Needs to be adjusted manually, you can set it as a parameter in the function if you wish.
...
local my_size = 10
Frame.Size = UDim2.fromOffset(Distance.Magnitude, my_size)
With both functions connected and some creativity
You can achieve something similar to the Among Us wire connecting puzzle like so :
Hope this helps fellow developers!
If you have any questions or run into any issues, feel free to ask.