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
