|
|
|
|
| local ReplicatedStorage = game:GetService("ReplicatedStorage")
|
| local CollectionService = game:GetService("CollectionService")
|
| local Players = game:GetService("Players")
|
| local RunService = game:GetService("RunService")
|
|
|
| local DraggingConfig = require(ReplicatedStorage:WaitForChild("Shared"):WaitForChild("DraggingConfig"))
|
| local DragEvent = ReplicatedStorage:WaitForChild("Events"):WaitForChild("DragEvent")
|
| local DropEvent = ReplicatedStorage:WaitForChild("Events"):WaitForChild("DropEvent")
|
|
|
|
|
| local activeDrags = {}
|
|
|
|
|
| local function canBeDragged(part)
|
| return CollectionService:HasTag(part, "Draggable") or CollectionService:HasTag(part, "TreeSegment")
|
| end
|
|
|
|
|
| local function dropObject(player)
|
| local dragData = activeDrags[player.UserId]
|
| if dragData then
|
|
|
| if dragData.dragAttachment then dragData.dragAttachment:Destroy() end
|
| if dragData.targetAttachment then dragData.targetAttachment:Destroy() end
|
| if dragData.alignPos then dragData.alignPos:Destroy() end
|
| if dragData.alignOri then dragData.alignOri:Destroy() end
|
|
|
|
|
| if dragData.part and dragData.part:IsDescendantOf(workspace) then
|
|
|
| pcall(function()
|
| dragData.part:SetNetworkOwner(nil)
|
| end)
|
| end
|
|
|
| activeDrags[player.UserId] = nil
|
| end
|
| end
|
|
|
|
|
| local function onDragRequest(player, targetPart, hitPoint)
|
| if not targetPart or not targetPart:IsA("BasePart") then return end
|
| if not canBeDragged(targetPart) then return end
|
|
|
| local char = player.Character
|
| if not char or not char:FindFirstChild("HumanoidRootPart") then return end
|
|
|
|
|
| local distance = (char.HumanoidRootPart.Position - targetPart.Position).Magnitude
|
| if distance > DraggingConfig.MaxGrabDistance then return end
|
|
|
|
|
| if activeDrags[player.UserId] then dropObject(player) end
|
|
|
|
|
| for _, dragData in pairs(activeDrags) do
|
| if dragData.part == targetPart then return end
|
| end
|
|
|
|
|
| local partAttachment = Instance.new("Attachment")
|
| partAttachment.Name = "DragAttachment"
|
| partAttachment.CFrame = targetPart.CFrame:ToObjectSpace(CFrame.new(hitPoint))
|
| partAttachment.Parent = targetPart
|
|
|
|
|
|
|
|
|
| local targetAttachment = Instance.new("Attachment")
|
| targetAttachment.Name = "TargetAttachment_Player" .. player.UserId
|
|
|
|
|
| targetAttachment.WorldCFrame = CFrame.new(char.Head.Position + char.Head.CFrame.LookVector * DraggingConfig.HoldDistance)
|
| targetAttachment.Parent = workspace.Terrain
|
|
|
| local alignPos = Instance.new("AlignPosition")
|
| alignPos.Attachment0 = partAttachment
|
| alignPos.Attachment1 = targetAttachment
|
| alignPos.MaxForce = DraggingConfig.AlignPositionMaxForce
|
| alignPos.Responsiveness = DraggingConfig.AlignPositionResponsiveness
|
| alignPos.Parent = targetPart
|
|
|
| local alignOri = Instance.new("AlignOrientation")
|
| alignOri.Attachment0 = partAttachment
|
| alignOri.Attachment1 = targetAttachment
|
| alignOri.MaxTorque = DraggingConfig.AlignOrientationMaxTorque
|
| alignOri.Responsiveness = DraggingConfig.AlignOrientationResponsiveness
|
| alignOri.Parent = targetPart
|
|
|
|
|
| pcall(function()
|
| targetPart:SetNetworkOwner(player)
|
| end)
|
|
|
|
|
| activeDrags[player.UserId] = {
|
| part = targetPart,
|
| dragAttachment = partAttachment,
|
| targetAttachment = targetAttachment,
|
| alignPos = alignPos,
|
| alignOri = alignOri
|
| }
|
| end
|
|
|
|
|
| local function onDropRequest(player)
|
| dropObject(player)
|
| end
|
|
|
|
|
| Players.PlayerRemoving:Connect(function(player)
|
| dropObject(player)
|
| end)
|
|
|
| DragEvent.OnServerEvent:Connect(onDragRequest)
|
| DropEvent.OnServerEvent:Connect(onDropRequest)
|
|
|