local Players = game:GetService("Players") local Workspace = game:GetService("Workspace") local plr = Players.LocalPlayer local ballParts = {} local function getCatchParts() local char = plr.Character if not char then return nil, nil end local wsModel = Workspace:FindFirstChild(plr.Name) local catchLeft, catchRight if char then for _, part in pairs(char:GetDescendants()) do if part:IsA("BasePart") then local name = part.Name:lower() if name:find("left") or name:find("catch") then catchLeft = catchLeft or part end if name:find("right") or name:find("catch") then catchRight = catchRight or part end end end end if wsModel then for _, part in pairs(wsModel:GetDescendants()) do if part:IsA("BasePart") then local name = part.Name:lower() if name:find("left") or name:find("catch") then catchLeft = catchLeft or part end if name:find("right") or name:find("catch") then catchRight = catchRight or part end end end end if not catchLeft and not catchRight then if char then catchLeft = char:FindFirstChild("LeftHand") or char:FindFirstChild("Left Arm") catchRight = char:FindFirstChild("RightHand") or char:FindFirstChild("Right Arm") end end return catchLeft, catchRight end local function hasTouchInterest(part) for _, child in pairs(part:GetChildren()) do if child:IsA("TouchTransmitter") then return true end end return false end local function isBall(part) if not part or not part:IsA("BasePart") then return false end if not part.Name:lower():find("ball") then return false end return hasTouchInterest(part) end local function onDescendantAdded(descendant) task.spawn(function() task.wait(0.1) if isBall(descendant) and descendant.Parent then ballParts[descendant] = true descendant.AncestryChanged:Connect(function() if not descendant:IsDescendantOf(Workspace) then ballParts[descendant] = nil end end) end end) end Workspace.DescendantAdded:Connect(onDescendantAdded) for _, descendant in pairs(Workspace:GetDescendants()) do if isBall(descendant) then ballParts[descendant] = true descendant.AncestryChanged:Connect(function() if not descendant:IsDescendantOf(Workspace) then ballParts[descendant] = nil end end) end end task.spawn(function() while true do task.wait() local char = plr.Character if not char or not char:FindFirstChild("HumanoidRootPart") then continue end local hrp = char.HumanoidRootPart local catchLeft, catchRight = getCatchParts() local target = catchLeft or catchRight if not target then continue end for ball in pairs(ballParts) do if ball and ball.Parent and ball:IsDescendantOf(Workspace) then local distance = (hrp.Position - ball.Position).Magnitude if distance <= 10 and not ball.Anchored then -- range pcall(function() ball.CanCollide = false ball.CFrame = target.CFrame ball.AssemblyLinearVelocity = Vector3.zero ball.AssemblyAngularVelocity = Vector3.zero end) end else ballParts[ball] = nil end end end end)