-- LocalScript in StarterPlayerScripts local Players = game:GetService("Players") local RunService = game:GetService("RunService") local UserInputService = game:GetService("UserInputService") local Debris = game:GetService("Debris") local player = Players.LocalPlayer local spawnedBalls = {} local grabbableMode = false local grabbedBall = nil local grabOffset = Vector3.new() local activeFunConnection -- Helper functions local function getCharacter() return player.Character or player.CharacterAdded:Wait() end local function getHRP() return getCharacter():WaitForChild("HumanoidRootPart") end local function updateLabel(label) label.Text = "Spawned balls: "..#spawnedBalls end -- UI Setup local screenGui = Instance.new("ScreenGui") screenGui.Name = "BallManagerUI" screenGui.ResetOnSpawn = false screenGui.Parent = player:WaitForChild("PlayerGui") local function makeDraggable(frame) local dragging, dragInput, dragStart, startPos frame.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then dragging = true dragStart = input.Position startPos = frame.Position input.Changed:Connect(function() if input.UserInputState == Enum.UserInputState.End then dragging = false end end) end end) frame.InputChanged:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then dragInput = input end end) UserInputService.InputChanged:Connect(function(input) if dragging and input == dragInput then local delta = input.Position - dragStart frame.Position = UDim2.new(startPos.X.Scale, startPos.X.Offset + delta.X, startPos.Y.Scale, startPos.Y.Offset + delta.Y) end end) end -- Main Frame local frame = Instance.new("Frame") frame.Size = UDim2.new(0, 300, 0, 330) frame.Position = UDim2.new(0.5, -150, 0.5, -165) frame.BackgroundColor3 = Color3.fromRGB(50,50,50) frame.Parent = screenGui makeDraggable(frame) -- Title local title = Instance.new("TextLabel") title.Size = UDim2.new(1,0,0,30) title.BackgroundTransparency = 1 title.Text = "Ball Management" title.TextColor3 = Color3.new(1,1,1) title.Font = Enum.Font.SourceSansBold title.TextSize = 20 title.Parent = frame -- Close Button local xButton = Instance.new("TextButton") xButton.Size = UDim2.new(0,30,0,30) xButton.Position = UDim2.new(1,-35,0,5) xButton.Text = "X" xButton.TextScaled = true xButton.BackgroundColor3 = Color3.fromRGB(170,0,0) xButton.Parent = frame -- Amount input local amountBox = Instance.new("TextBox") amountBox.Size = UDim2.new(0,100,0,30) amountBox.Position = UDim2.new(0,10,0,50) amountBox.PlaceholderText = "Amount" amountBox.Text = "" amountBox.TextScaled = true amountBox.Parent = frame -- Spawn Button local spawnButton = Instance.new("TextButton") spawnButton.Size = UDim2.new(0,100,0,30) spawnButton.Position = UDim2.new(0,10,0,90) spawnButton.Text = "Spawn Balls" spawnButton.TextScaled = true spawnButton.BackgroundColor3 = Color3.fromRGB(0,170,0) spawnButton.Parent = frame -- Delete All local deleteAllButton = Instance.new("TextButton") deleteAllButton.Size = UDim2.new(0,100,0,30) deleteAllButton.Position = UDim2.new(0,10,0,130) deleteAllButton.Text = "Delete All Balls" deleteAllButton.TextScaled = true deleteAllButton.BackgroundColor3 = Color3.fromRGB(170,0,0) deleteAllButton.Parent = frame -- Delete Amount local deleteAmountButton = Instance.new("TextButton") deleteAmountButton.Size = UDim2.new(0,100,0,30) deleteAmountButton.Position = UDim2.new(0,130,0,90) deleteAmountButton.Text = "Delete Amount" deleteAmountButton.TextScaled = true deleteAmountButton.BackgroundColor3 = Color3.fromRGB(255,140,0) deleteAmountButton.Parent = frame -- Emergency Recovery local emergencyButton = Instance.new("TextButton") emergencyButton.Size = UDim2.new(0,220,0,30) emergencyButton.Position = UDim2.new(0,10,0,170) emergencyButton.Text = "Emergency Recovery" emergencyButton.TextScaled = true emergencyButton.BackgroundColor3 = Color3.fromRGB(0,0,255) emergencyButton.Parent = frame -- Grabbable Mode local grabbableButton = Instance.new("TextButton") grabbableButton.Size = UDim2.new(0,220,0,30) grabbableButton.Position = UDim2.new(0,10,0,210) grabbableButton.Text = "Toggle Grabbable Balls: OFF" grabbableButton.TextScaled = true grabbableButton.BackgroundColor3 = Color3.fromRGB(100,100,255) grabbableButton.Parent = frame -- Fun Button local funButton = Instance.new("TextButton") funButton.Size = UDim2.new(0,220,0,30) funButton.Position = UDim2.new(0,10,0,250) funButton.Text = "Fun" funButton.TextScaled = true funButton.BackgroundColor3 = Color3.fromRGB(255,100,255) funButton.Parent = frame -- Spawned balls label local spawnedLabel = Instance.new("TextLabel") spawnedLabel.Size = UDim2.new(0,240,0,30) spawnedLabel.Position = UDim2.new(0,10,0,290) spawnedLabel.BackgroundTransparency = 1 spawnedLabel.TextColor3 = Color3.new(1,1,1) spawnedLabel.TextScaled = true spawnedLabel.Text = "Spawned balls: 0" spawnedLabel.Parent = frame -- Ball Functions local function spawnBalls(amount) local hrp = getHRP() for i = 1, amount do local ball = Instance.new("Part") ball.Shape = Enum.PartType.Ball ball.Size = Vector3.new(1,1,1) ball.Position = hrp.Position + hrp.CFrame.LookVector * (5+i) + hrp.CFrame.RightVector * ((i%3)-1) * 2 ball.Anchored = false ball.BrickColor = BrickColor.random() ball.Parent = workspace table.insert(spawnedBalls, ball) local bv = Instance.new("BodyVelocity") bv.Velocity = hrp.CFrame.LookVector * 15 bv.MaxForce = Vector3.new(4000,4000,4000) bv.Parent = ball Debris:AddItem(bv,0.2) end updateLabel(spawnedLabel) end local function deleteAllBalls() for _, ball in pairs(spawnedBalls) do if ball and ball.Parent then ball:Destroy() end end spawnedBalls = {} updateLabel(spawnedLabel) end local function deleteAmountBalls(amount) for i = 1, amount do local ball = table.remove(spawnedBalls) if ball and ball.Parent then ball:Destroy() end end updateLabel(spawnedLabel) end local function emergencyRecovery() local hrp = getHRP() for _, ball in pairs(spawnedBalls) do if ball and ball.Parent then ball.Position = hrp.Position + hrp.CFrame.LookVector * 5 end end end -- Input Handlers for Grabbing local function onInputBegan(input) if grabbableMode and input.UserInputType ~= Enum.UserInputType.Keyboard then local mousePos = input.Position local closest, minDist = nil, math.huge for _, ball in pairs(spawnedBalls) do if ball and ball.Parent then local screenPos, onScreen = workspace.CurrentCamera:WorldToScreenPoint(ball.Position) if onScreen then local dist = (Vector2.new(screenPos.X, screenPos.Y) - Vector2.new(mousePos.X, mousePos.Y)).Magnitude if dist < minDist and dist < 50 then closest = ball minDist = dist end end end end if closest then grabbedBall = closest local ray = workspace.CurrentCamera:ScreenPointToRay(mousePos.X, mousePos.Y) grabOffset = closest.Position - ray.Origin end end end local function onInputChanged(input) if grabbedBall then local ray = workspace.CurrentCamera:ScreenPointToRay(input.Position.X,input.Position.Y) grabbedBall.Position = ray.Origin + grabOffset end end local function onInputEnded(input) grabbedBall = nil end -- Fun UI local funGui local function openFunUI() if funGui then funGui:Destroy() end if activeFunConnection then activeFunConnection:Disconnect() activeFunConnection = nil end funGui = Instance.new("Frame") funGui.Size = UDim2.new(0,220,0,250) funGui.Position = UDim2.new(0,50,0,50) funGui.BackgroundColor3 = Color3.fromRGB(80,80,80) funGui.Parent = screenGui makeDraggable(funGui) -- Title local fTitle = Instance.new("TextLabel") fTitle.Size = UDim2.new(1,0,0,30) fTitle.BackgroundTransparency = 1 fTitle.Text = "Fun Menu" fTitle.TextColor3 = Color3.new(1,1,1) fTitle.TextScaled = true fTitle.Parent = funGui -- X button local fxButton = Instance.new("TextButton") fxButton.Size = UDim2.new(0,30,0,30) fxButton.Position = UDim2.new(1,-35,0,5) fxButton.Text = "X" fxButton.TextScaled = true fxButton.BackgroundColor3 = Color3.fromRGB(170,0,0) fxButton.Parent = funGui fxButton.MouseButton1Click:Connect(function() if activeFunConnection then activeFunConnection:Disconnect() activeFunConnection=nil end funGui:Destroy() end) -- Cancel Button local cancelButton = Instance.new("TextButton") cancelButton.Size = UDim2.new(0,180,0,30) cancelButton.Position = UDim2.new(0,20,0,210) cancelButton.Text = "Cancel Current Action" cancelButton.TextScaled = true cancelButton.BackgroundColor3 = Color3.fromRGB(255,0,255) cancelButton.Parent = funGui cancelButton.MouseButton1Click:Connect(function() if activeFunConnection then activeFunConnection:Disconnect() activeFunConnection=nil end end) -- Fun Buttons local funOptions = { {Name="Float Around Head", Func=function() local hrp = getHRP() local radius = 5 local angle = 0 if activeFunConnection then activeFunConnection:Disconnect() end activeFunConnection = RunService.Heartbeat:Connect(function(dt) angle = angle + dt*2 for i, ball in pairs(spawnedBalls) do if ball and ball.Parent then local offset = Vector3.new(math.cos(angle+i)*radius,3,math.sin(angle+i)*radius) ball.CFrame = CFrame.new(hrp.Position + offset) end end end) end}, {Name="Orbit Horizontally", Func=function() local hrp = getHRP() local radius = 5 local angle = 0 if activeFunConnection then activeFunConnection:Disconnect() end activeFunConnection = RunService.Heartbeat:Connect(function(dt) angle = angle + dt*3 for i, ball in pairs(spawnedBalls) do if ball and ball.Parent then local offset = Vector3.new(math.cos(angle+i)*radius, 2 + math.sin(angle*2+i), math.sin(angle+i)*radius) ball.CFrame = CFrame.new(hrp.Position + offset) end end end) end}, {Name="Bounce Up and Down", Func=function() if activeFunConnection then activeFunConnection:Disconnect() end local t = 0 activeFunConnection = RunService.Heartbeat:Connect(function(dt) t = t + dt*4 for i, ball in pairs(spawnedBalls) do if ball and ball.Parent then local pos = ball.Position ball.Position = Vector3.new(pos.X, 2 + math.sin(t+i), pos.Z) end end end) end}, {Name="Random Fireworks", Func=function() if activeFunConnection then activeFunConnection:Disconnect() end local t = 0 activeFunConnection = RunService.Heartbeat:Connect(function(dt) t = t + dt for i, ball in pairs(spawnedBalls) do if ball and ball.Parent then ball.Position = Vector3.new(math.random(-20,20), math.random(5,15), math.random(-20,20)) end end end) end} } for i,opt in pairs(funOptions) do local btn = Instance.new("TextButton") btn.Size = UDim2.new(0,180,0,30) btn.Position = UDim2.new(0,20,0,40+40*(i-1)) btn.Text = opt.Name btn.TextScaled = true btn.BackgroundColor3 = Color3.fromRGB(100,255,100) btn.Parent = funGui btn.MouseButton1Click:Connect(opt.Func) end end -- Connections spawnButton.MouseButton1Click:Connect(function() local amt = tonumber(amountBox.Text) or 1 spawnBalls(amt) end) deleteAllButton.MouseButton1Click:Connect(deleteAllBalls) deleteAmountButton.MouseButton1Click:Connect(function() local amt = tonumber(amountBox.Text) or 1 deleteAmountBalls(amt) end) emergencyButton.MouseButton1Click:Connect(emergencyRecovery) xButton.MouseButton1Click:Connect(function() deleteAllBalls() if activeFunConnection then activeFunConnection:Disconnect() activeFunConnection=nil end screenGui:Destroy() end) grabbableButton.MouseButton1Click:Connect(function() grabbableMode = not grabbableMode grabbableButton.Text = "Toggle Grabbable Balls: "..(grabbableMode and "ON" or "OFF") end) funButton.MouseButton1Click:Connect(openFunUI) -- Input Handlers UserInputService.InputBegan:Connect(function(input) onInputBegan(input) end) UserInputService.InputChanged:Connect(function(input) onInputChanged(input) end) UserInputService.InputEnded:Connect(function(input) onInputEnded(input) end) -- Handle character respawn player.CharacterAdded:Connect(function() RunService.Heartbeat:Wait() emergencyRecovery() end)