I’ve been trying to make a dragging script, similar to that of a Lumber Tycoon 2. I made 2 scripts. The first one basically checks if part can be picked up, and highlights it, if it can be picked up. Script goes through several checks such as “is part anchored” or “is part connected to another anchored part” or “is part connected to a seat, that is currently being occupied”. The idea was that when all checks return positive, a function is being bind to a players mouse, so that when he holds down mouse, it moves the part to mouse location, and when he releases mouse button, the part is also being released. I did not really come up how would that function look, but here is the script:
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ContextActionService = game:GetService("ContextActionService")
local TweenService = game:GetService("TweenService")
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local camera = workspace.CurrentCamera
local highlight = ReplicatedStorage.PlayersHighlight
local function GetParts(chosenPart)
local toCheck = {chosenPart}
local checked = {}
while #toCheck > 0 do
for i, part in pairs(toCheck) do
if table.find(checked, part) then
continue
else
local directlyConnectedParts = part:GetConnectedParts(true)
local indirectlyConnectedParts = {}
local joints = part:GetJoints()
for i, joint in pairs(joints) do
if joint:IsA("HingeConstraint") then
local hinge = joint
if hinge.Attachment0.Parent == part then
if not table.find(toCheck, hinge.Attachment1.Parent) then
table.insert(indirectlyConnectedParts, hinge.Attachment1.Parent)
end
elseif hinge.Attachment1.Parent == part then
if not table.find(toCheck, hinge.Attachment0.Parent) then
table.insert(indirectlyConnectedParts, hinge.Attachment0.Parent)
end
end
end
end
for i, con in pairs(indirectlyConnectedParts) do
table.insert(toCheck, con)
end
for i, v in pairs(directlyConnectedParts) do
if not table.find(toCheck, v) then
table.insert(toCheck, v)
end
end
table.insert(checked, part)
end
end
if #toCheck == #checked then
break
end
end
return checked
end
local function Drag(Name, inputState, inputObject)
if Name == "Dragging" then
if inputState == Enum.UserInputState.Begin then
print("clicked")
elseif inputState == Enum.UserInputState.End then
print("released")
end
end
end
local MapCheck = false
local RangeCheck = false
local AnchorCheck = false
local ButtonCheck = false
local ConnectionsCheck = false
local SeatsCheck = false
RunService.RenderStepped:Connect(function()
local target = mouse.Target
highlight.Adornee = target
if target ~= nil then
if target.Parent ~= workspace.Map then
MapCheck = true
else
MapCheck = false
end
if (player.Character:FindFirstChild("HumanoidRootPart").Position - target.Position).Magnitude <= 20 then
RangeCheck = true
else
RangeCheck = false
end
if target.Anchored == false then
AnchorCheck = true
else
AnchorCheck = false
end
if target:FindFirstChild("ClickDetector") == nil then
ButtonCheck = true
else
ButtonCheck = false
end
local allConnectedParts = GetParts(target)
local connectedParts = target:GetConnectedParts(true)
local anchoredConnections = {}
local occupiedSeats = {}
for i, part in pairs(connectedParts) do
if part.Anchored == true then
table.insert(anchoredConnections, part)
end
end
if #anchoredConnections == 0 then
ConnectionsCheck = true
else
ConnectionsCheck = false
end
for i, part in pairs(allConnectedParts) do
if part:IsA("Seat") or part:IsA("VehicleSeat") then
if part.Occupant ~= nil then
table.insert(occupiedSeats, part)
end
end
end
if #occupiedSeats == 0 then
SeatsCheck = true
else
SeatsCheck = false
end
if MapCheck == true and RangeCheck == true and ButtonCheck == true and AnchorCheck == true and SeatsCheck == true and ConnectionsCheck == true then
highlight.Enabled = true
ContextActionService:BindAction("Dragging", Drag, false, Enum.UserInputType.MouseButton1)
else
highlight.Enabled = false
ContextActionService:UnbindAction("Dragging")
end
else
highlight.Enabled = false
ContextActionService:UnbindAction("Dragging")
end
end)
It works as of now with the current version of the bind function that just prints out if you clicked or released the button.
I also made a 2nd script. Its much shorter and its a somewhat of a prototype I would use for the dragging system. The part is being held away from the players camera on specific distance, that also includes the cameras current zoom out distance referred as “difference”. Here is how it looks:
local TweenService = game:GetService("TweenService")
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local camera = workspace.CurrentCamera
camera.CameraType = Enum.CameraType.Scriptable
local RunService = game:GetService("RunService")
local part = Instance.new("Part")
part.Anchored = false
part.Transparency = 0.5
part.Parent = workspace
RunService.RenderStepped:Connect(function()
local direction = mouse.UnitRay.Direction
local difference = (camera.CFrame.Position - player.Character:WaitForChild("Head").Position).Magnitude
local goal = {
Position = Vector3.new(camera.CFrame.Position.X + direction.X * (10 + difference), camera.CFrame.Position.Y + direction.Y * (10 + difference), camera.CFrame.Position.Z + direction.Z * (10 + difference))
}
local tween = TweenService:Create(part, TweenInfo.new(0.01, Enum.EasingStyle.Sine, Enum.EasingDirection.In, -1, false), goal)
tween:Play()
end)
It also works pretty well, but it still has some issues. For example, part clips through other parts probably because I just change the parts position, However its not always the case, and it even looks really cool sometimes.
How would I potentially fix the issue with clipping part, and how would I bind that function in the first script?

