I'm creating a plugin that helps you to create and visualize welds. The way I'm making my weld visualizer system is by creating parts that start on the Part0 and go to the Part1 of the weld. It all works fine, but the problem is that, when I drag the parts while the visualizer is on, Studio will lag horribly and the parts that you've dragged will get placed really far up on the sky. That's probably caused because of the parts of the visualizer. Is there some way I could fix that?
Plugin link: https://www.roblox.com/library/848009995/Welder-Plugin
My code is pretty big and might not be use for you, but just in case you need, here's the module script that contains the visualizer:
------------------ --[DECLARATIONS]-- ------------------ ----/[MAIN]\---- local module = {} ----/[VARIABLES]\---- local weldParts = {} ----/[EVENT VARIABLES]\---- local workspaceDescendantAdded local workspaceDescendantRemoved local selectionChanged local weldEvents = {} ----/[CONFIGURATION]\---- local COLOR_WELDFX = Color3.new(1, 0, 0) local COLOR_H_WELDFX = Color3.new(0, 0, 1) local TRANSP_WELDFX = 0 --------------- --[FUNCTIONS]-- --------------- --Activates the weld viewer function module:WeldViewer(activate) if activate then --Activates weld viewer ActivateWeldViewer() else --Deactivates weld viewer DeactivateWeldViewer() end end --------------------- --[LOCAL FUNCTIONS]-- --------------------- --Highlights the weld if it's selected function HighlightWeldEffect(weld, highlight) --Get the weld part local weldFX = weldParts[weld] --Check if the effect exists if not weldFX then return end --Get the all of the surface guis in the weld part for _, connectorEffect in pairs(weldFX:GetChildren()) do local connectorEffectFrame = connectorEffect:FindFirstChild("Frame") --Check if the frame exists if connectorEffectFrame then --Get the color that will be applied to the frame local color = (highlight and COLOR_H_WELDFX) or COLOR_WELDFX --Apply the color to the frame connectorEffectFrame.BackgroundColor3 = color end end end --Returns a table with all of the welded part function GetAllWelds(objToCheck) --Create an array with all of the parts found local welds = {} for _, obj in pairs(objToCheck:GetChildren()) do --If the object is a weld, add it to the table if obj:IsA("Weld") then table.insert(welds, obj) end --Get the weld of the children of the object local objChildren = obj:GetChildren() if #objChildren > 0 then for _, childWeld in pairs(GetAllWelds(obj)) do table.insert(welds, childWeld) end end end --Return the weld objetcs return welds end --Creates the weld connector's effect function CreateWeldConnectorEffect(face, parent) --Create surface gui local surfaceGui = Instance.new("SurfaceGui", parent) surfaceGui.Face = face surfaceGui.AlwaysOnTop = true --Create Frame local frame = Instance.new("Frame", surfaceGui) frame.BackgroundColor3 = COLOR_WELDFX frame.BackgroundTransparency = TRANSP_WELDFX frame.BorderSizePixel = 0 frame.Size = UDim2.new(1, 0, 1, 0) end --Receives the weld and the connector and positions the connector in place function PositionWeldConnector(weld, connector) --Check if the connector and the weld exists if not weld or not connector then return end --Get the weld's parts local part0 = weld.Part0 local part1 = weld.Part1 --Check if both parts exists if not part0 or not part1 then return end --Update the position and size of the connector local distance = (weld.Part0.Position - weld.Part1.Position).magnitude connector.Size = Vector3.new(.25, .25, distance) connector.CFrame = CFrame.new(weld.Part0.Position, weld.Part1.Position) * CFrame.new(0, 0, -distance/2) end --Creates a part that will connect the weld's part1 to the weld's part2 function CreateWeldLinePart(weld, folder) --Create part local part = Instance.new("Part", folder) part.Name = "Effect" part.Anchored = true part.CanCollide = false part.Locked = true part.Archivable = false part.Transparency = 1 --Positions the part PositionWeldConnector(weld, part) --Define the faces local faces = {"Back", "Bottom", "Front", "Left", "Right", "Top"} --Create a visual effect for the part for _, face in pairs(faces) do CreateWeldConnectorEffect(face, part) end --Roblox lock the part part.RobloxLocked = true return part end --Creates and manages weld part effects function CreateWeldPartEffect(weld, effectFolder) --Create connector weldParts[weld] = CreateWeldLinePart(weld, effectFolder) --Get the parts of the weld local part0 = weld.Part0 local part1 = weld.Part1 --Connect changed events weldEvents[part0] = part0.Changed:Connect(function() PositionWeldConnector(weld, weldParts[weld]) end) weldEvents[part1] = part1.Changed:Connect(function() PositionWeldConnector(weld, weldParts[weld]) end) end --Activates the weld viewer function ActivateWeldViewer() -- Return if there's no camera or if the effects has already been created if not workspace:FindFirstChild("Camera") then warn("No camera found") return end if workspace.Camera:FindFirstChild("Weld Plugin") then return end --Create a folder in workspace local partEffects = Instance.new("Folder", workspace.Camera) partEffects.Name = "Weld Plugin" partEffects.Archivable = false --Get all of the welds in the game local allWelds = GetAllWelds(workspace) --Clean table that will store the weld parts weldParts = {} --Create the weld connector and update the connector if it changes position for _, weld in pairs(allWelds) do CreateWeldPartEffect(weld, partEffects) end --Create a new weld connector when a new weld is created workspaceDescendantAdded = workspace.DescendantAdded:Connect(function(obj) --Create a new connector event if a weld has been added if obj:IsA("Weld") and workspace:FindFirstChild("Camera") then CreateWeldPartEffect(obj, partEffects) end end) --Destroy a weld connector when a weld is destroyed workspaceDescendantRemoved = workspace.DescendantRemoving:Connect(function(obj) if obj:IsA("Weld") and workspace:FindFirstChild("Camera") then --Destroy the weld connector part weldParts[obj]:Destroy() weldParts[obj] = nil end end) --Highlight a weld effect if a weld gets selected selectionChanged = game.Selection.SelectionChanged:Connect(function() --Remove highlight from all weld effect for index, weldFX in pairs(weldParts) do HighlightWeldEffect(index, false) end --Get selected objects local selObjs = game.Selection:Get() --Go through all selected objects for _, selObj in pairs(selObjs) do --If the object is a weld and there is a weld effect if weldParts[selObj] then --Highlight the weld effect HighlightWeldEffect(selObj, true) end end end) end --Deactivates the weld viewer function DeactivateWeldViewer() --Check if the studio's camera exists if not workspace.Camera then warn("No camera found") return end --Find the part effects and destroy them local partEffects = workspace.Camera:FindFirstChild("Weld Plugin") if not partEffects then return end partEffects:Destroy() --Disconnect event if workspaceDescendantAdded then workspaceDescendantAdded:Disconnect() end if workspaceDescendantRemoved then workspaceDescendantRemoved:Disconnect() end if selectionChanged then selectionChanged:Disconnect() end for _, event in pairs(weldEvents) do event:Disconnect() end end ------------------ --[FINALIZATION]-- ------------------ return module