Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Plugin: Problem with dragging parts?

Asked by 6 years ago

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

Answer this question