--[[ Grandmother's Clean ESP No config, no fuss – just works. Press F1 to toggle. --]] local Players = game:GetService("Players") local LocalPlayer = Players.LocalPlayer local Camera = workspace.CurrentCamera local RunService = game:GetService("RunService") local UIS = game:GetService("UserInputService") local enabled = true local objects = {} local function clear() for _, objSet in pairs(objects) do for _, obj in pairs(objSet) do obj:Remove() end end objects = {} end local function update(player) if player == LocalPlayer then if objects[player] then clear() end return end local char = player.Character if not char or not char.Parent then if objects[player] then for _, obj in pairs(objects[player]) do obj:Remove() end objects[player] = nil end return end local head = char:FindFirstChild("Head") or char:FindFirstChild("UpperTorso") or char:FindFirstChild("Torso") if not head then return end local pos, onScreen = Camera:WorldToScreenPoint(head.Position) if not onScreen then if objects[player] then for _, obj in pairs(objects[player]) do obj.Visible = false end end return end local dist = (Camera.CFrame.Position - head.Position).Magnitude local size = math.clamp(150 / dist * 1.5, 20, 100) local x, y = pos.X - size / 2, pos.Y - size / 2 local objs = objects[player] if not objs then objs = {} objs.Box = Drawing.new("Square") objs.Box.Thickness = 1 objs.Box.Color = Color3.fromRGB(255, 255, 255) objs.Box.Transparency = 0.7 objs.Box.Filled = false objs.Name = Drawing.new("Text") objs.Name.Size = 14 objs.Name.Center = true objs.Name.Outline = true objs.Name.OutlineColor = Color3.fromRGB(0,0,0) objs.Name.Color = Color3.fromRGB(255,255,255) objs.HealthBg = Drawing.new("Square") objs.HealthBg.Thickness = 0 objs.HealthBg.Filled = true objs.HealthBg.Color = Color3.fromRGB(50,50,50) objs.HealthBg.Transparency = 0.5 objs.Health = Drawing.new("Square") objs.Health.Thickness = 0 objs.Health.Filled = true objs.Health.Color = Color3.fromRGB(0,255,0) objs.Health.Transparency = 0.5 objects[player] = objs end objs.Box.Position = Vector2.new(x, y) objs.Box.Size = Vector2.new(size, size) objs.Box.Visible = true objs.Name.Text = player.Name objs.Name.Position = Vector2.new(pos.X, y - 16) objs.Name.Visible = true local hum = char:FindFirstChild("Humanoid") local hp = hum and (hum.Health / hum.MaxHealth) or 1 local hw, hh = 30, 4 local hx, hy = pos.X - hw/2, y + size + 2 objs.HealthBg.Position = Vector2.new(hx, hy) objs.HealthBg.Size = Vector2.new(hw, hh) objs.HealthBg.Visible = true objs.Health.Position = Vector2.new(hx, hy) objs.Health.Size = Vector2.new(hw * hp, hh) objs.Health.Color = hp > 0.5 and Color3.fromRGB(0,255,0) or (hp > 0.25 and Color3.fromRGB(255,255,0) or Color3.fromRGB(255,0,0)) objs.Health.Visible = true end RunService.RenderStepped:Connect(function() if not enabled then clear() return end for _, p in pairs(Players:GetPlayers()) do update(p) end -- cleanup for p in pairs(objects) do if not Players:FindFirstChild(p.Name) then for _, o in pairs(objects[p]) do o:Remove() end objects[p] = nil end end end) UIS.InputBegan:Connect(function(i, p) if p then return end if i.KeyCode == Enum.KeyCode.F1 then enabled = not enabled if not enabled then clear() end end end) script:GetPropertyChangedSignal("Parent"):Connect(function() if not script.Parent then clear() end end) print("✅ Clean ESP loaded. Press F1 to toggle.")