| |
|
| |
|
| | 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)
|
| |
|