
Key Required

--[[
Drone ESP + GUI for ПАНЦИР
Toggle panel: ON/OFF highlights for Workspace.Drones
BOT (red) vs PLAYER (blue) via IsPlayerDrone / OwnerUserId
]]
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
-- tear down previous full session (ESP + GUI)
if type(_G.UAI_DestroyDroneESP) == "function" then
pcall(_G.UAI_DestroyDroneESP)
elseif type(_G.UAI_StopDroneESP) == "function" then
pcall(_G.UAI_StopDroneESP)
end
local LOCAL = Players.LocalPlayer
local PLAYER_GUI = LOCAL:WaitForChild("PlayerGui")
local FOLDER_MAIN = workspace:WaitForChild("Drones"):WaitForChild("SpawnedDrones")
local FOLDER_SCOUT = workspace.Drones:FindFirstChild("Scout")
and workspace.Drones.Scout:FindFirstChild("Spawned")
local COLOR_BOT = Color3.fromRGB(255, 70, 70)
local COLOR_PLAYER = Color3.fromRGB(60, 180, 255)
local OUTLINE = Color3.fromRGB(255, 255, 255)
local TEXT_BOT = Color3.fromRGB(255, 180, 180)
local TEXT_PLAYER = Color3.fromRGB(160, 230, 255)
local MAX_DIST = 20000
local tracked = {}
local folderConns = {}
local updateConn: RBXScriptConnection? = nil
local espEnabled = false
local guiConns = {}
local screenGui: ScreenGui? = nil
local function getDroneType(drone: Model): string
local named = drone:GetAttribute("DroneName")
if typeof(named) == "string" and named ~= "" then
return named
end
for _, child in ipairs(drone:GetChildren()) do
if child:IsA("Model") and child.Name ~= "UAI_DroneESP" then
return child.Name
end
end
return "Drone"
end
local function getAnchor(drone: Model): BasePart?
if drone.PrimaryPart then
return drone.PrimaryPart
end
local body = drone:FindFirstChild("Body", true)
if body and body:IsA("BasePart") then
return body
end
return drone:FindFirstChildWhichIsA("BasePart", true)
end
local function getRootPos(): Vector3?
local char = LOCAL.Character
if not char then
return nil
end
local hrp = char:FindFirstChild("HumanoidRootPart")
return hrp and hrp.Position
end
local function resolvePilotName(userId: number?): string?
if not userId or userId <= 0 then
return nil
end
local plr = Players:GetPlayerByUserId(userId)
if plr then
return plr.DisplayName ~= "" and plr.DisplayName or plr.Name
end
local ok, name = pcall(function()
return Players:GetNameFromUserIdAsync(userId)
end)
if ok and typeof(name) == "string" then
return name
end
return tostring(userId)
end
local function readControl(drone: Model)
local isPlayer = drone:GetAttribute("IsPlayerDrone") == true
local ownerId = drone:GetAttribute("OwnerUserId")
if typeof(ownerId) ~= "number" then
ownerId = nil
end
if ownerId and ownerId > 0 then
isPlayer = true
end
local pilot = isPlayer and resolvePilotName(ownerId) or nil
return isPlayer, ownerId, pilot
end
local function applyVisual(data, isPlayer: boolean)
local fill = isPlayer and COLOR_PLAYER or COLOR_BOT
local text = isPlayer and TEXT_PLAYER or TEXT_BOT
data.highlight.FillColor = fill
data.highlight.OutlineColor = OUTLINE
data.label.TextColor3 = text
data.isPlayer = isPlayer
end
local function countTracked(): (number, number, number)
local bots, players, total = 0, 0, 0
for _, data in pairs(tracked) do
total += 1
if data.isPlayer then
players += 1
else
bots += 1
end
end
return total, bots, players
end
local statusLabel: TextLabel? = nil
local toggleBtn: TextButton? = nil
local function refreshGui()
local total, bots, players = countTracked()
if statusLabel then
if espEnabled then
statusLabel.Text = string.format("ON | %d (BOT %d / PLAYER %d)", total, bots, players)
statusLabel.TextColor3 = Color3.fromRGB(120, 255, 160)
else
statusLabel.Text = "OFF | ESP выключен"
statusLabel.TextColor3 = Color3.fromRGB(200, 200, 200)
end
end
if toggleBtn then
if espEnabled then
toggleBtn.Text = "ВЫКЛЮЧИТЬ"
toggleBtn.BackgroundColor3 = Color3.fromRGB(180, 50, 50)
else
toggleBtn.Text = "ВКЛЮЧИТЬ"
toggleBtn.BackgroundColor3 = Color3.fromRGB(40, 140, 70)
end
end
end
local function untrack(drone: Model)
local data = tracked[drone]
if not data then
return
end
for _, c in ipairs(data.conns or {}) do
c:Disconnect()
end
if data.highlight then
data.highlight:Destroy()
end
if data.billboard then
data.billboard:Destroy()
end
tracked[drone] = nil
end
local function clearAllTracked()
for drone in pairs(tracked) do
untrack(drone)
end
end
local function track(drone: Model)
if not espEnabled then
return
end
if tracked[drone] then
return
end
if not drone:IsA("Model") or drone.Name ~= "Drone" then
return
end
local oldHl = drone:FindFirstChild("UAI_DroneESP")
if oldHl then
oldHl:Destroy()
end
local oldBb = drone:FindFirstChild("UAI_DroneESP_BB")
if oldBb then
oldBb:Destroy()
end
local anchor = getAnchor(drone)
if not anchor then
return
end
local isPlayer, ownerId, pilot = readControl(drone)
local typeName = getDroneType(drone)
local hl = Instance.new("Highlight")
hl.Name = "UAI_DroneESP"
hl.Adornee = drone
hl.FillTransparency = 0.55
hl.OutlineTransparency = 0
hl.DepthMode = Enum.HighlightDepthMode.AlwaysOnTop
hl.Parent = drone
local bb = Instance.new("BillboardGui")
bb.Name = "UAI_DroneESP_BB"
bb.Adornee = anchor
bb.AlwaysOnTop = true
bb.Size = UDim2.fromOffset(200, 48)
bb.StudsOffset = Vector3.new(0, 3, 0)
bb.MaxDistance = MAX_DIST or 100000
bb.Parent = drone
local label = Instance.new("TextLabel")
label.Name = "Label"
label.BackgroundTransparency = 1
label.Size = UDim2.fromScale(1, 1)
label.Font = Enum.Font.GothamBold
label.TextSize = 14
label.TextStrokeTransparency = 0.3
label.TextWrapped = true
label.Parent = bb
local conns = {}
table.insert(conns, drone.AncestryChanged:Connect(function(_, parent)
if parent == nil then
untrack(drone)
refreshGui()
end
end))
local data = {
highlight = hl,
billboard = bb,
label = label,
typeName = typeName,
isPlayer = isPlayer,
ownerId = ownerId,
pilot = pilot,
conns = conns,
}
applyVisual(data, isPlayer)
tracked[drone] = data
end
local function scanFolder(folder: Instance?)
if not folder then
return
end
for _, child in ipairs(folder:GetChildren()) do
if child:IsA("Model") and child.Name == "Drone" then
track(child)
end
end
end
local function disconnectFolderHooks()
for _, c in ipairs(folderConns) do
c:Disconnect()
end
table.clear(folderConns)
end
local function hookFolder(folder: Instance?)
if not folder then
return
end
scanFolder(folder)
table.insert(folderConns, folder.ChildAdded:Connect(function(child)
task.defer(function()
if espEnabled and child.Parent and child:IsA("Model") and child.Name == "Drone" then
track(child)
refreshGui()
end
end)
end))
table.insert(folderConns, folder.ChildRemoved:Connect(function(child)
if tracked[child] then
untrack(child)
refreshGui()
end
end))
end
local function stopUpdate()
if updateConn then
updateConn:Disconnect()
updateConn = nil
end
end
local function startUpdate()
stopUpdate()
updateConn = RunService.Heartbeat:Connect(function()
if not espEnabled then
return
end
local root = getRootPos()
if not root then
return
end
for drone, data in pairs(tracked) do
if drone.Parent and data.label then
local isPlayer, ownerId, pilot = readControl(drone)
data.typeName = getDroneType(drone)
if isPlayer ~= data.isPlayer or ownerId ~= data.ownerId or pilot ~= data.pilot then
data.ownerId = ownerId
data.pilot = pilot
applyVisual(data, isPlayer)
end
local anchor = getAnchor(drone)
if anchor then
local dist = (anchor.Position - root).Magnitude
if MAX_DIST and dist > MAX_DIST then
data.highlight.Enabled = false
data.billboard.Enabled = false
else
data.highlight.Enabled = true
data.billboard.Enabled = true
local who
if isPlayer then
who = pilot and ("PLAYER:" .. pilot) or "PLAYER"
else
who = "BOT"
end
data.label.Text = string.format("%s\n%s [%.0fm]", data.typeName, who, dist)
end
end
else
untrack(drone)
end
end
end)
end
local function setEspEnabled(on: boolean)
if on == espEnabled then
refreshGui()
return
end
espEnabled = on
if on then
disconnectFolderHooks()
hookFolder(FOLDER_MAIN)
hookFolder(FOLDER_SCOUT)
startUpdate()
else
stopUpdate()
disconnectFolderHooks()
clearAllTracked()
end
refreshGui()
end
local function destroyGui()
for _, c in ipairs(guiConns) do
c:Disconnect()
end
table.clear(guiConns)
if screenGui then
screenGui:Destroy()
screenGui = nil
end
statusLabel = nil
toggleBtn = nil
end
local function makeCorner(parent: Instance, radius: number)
local c = Instance.new("UICorner")
c.CornerRadius = UDim.new(0, radius)
c.Parent = parent
return c
end
local function makeStroke(parent: Instance, color: Color3, thickness: number)
local s = Instance.new("UIStroke")
s.Color = color
s.Thickness = thickness
s.ApplyStrokeMode = Enum.ApplyStrokeMode.Border
s.Parent = parent
return s
end
local function createGui()
destroyGui()
local old = PLAYER_GUI:FindFirstChild("UAI_DroneESP_Gui")
if old then
old:Destroy()
end
local gui = Instance.new("ScreenGui")
gui.Name = "UAI_DroneESP_Gui"
gui.ResetOnSpawn = false
gui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling
gui.DisplayOrder = 100
gui.Parent = PLAYER_GUI
screenGui = gui
local panel = Instance.new("Frame")
panel.Name = "Panel"
panel.Size = UDim2.fromOffset(220, 128)
panel.Position = UDim2.new(0, 16, 0.35, 0)
panel.BackgroundColor3 = Color3.fromRGB(22, 24, 30)
panel.BackgroundTransparency = 0.12
panel.BorderSizePixel = 0
panel.Active = true
panel.Parent = gui
makeCorner(panel, 10)
makeStroke(panel, Color3.fromRGB(70, 80, 100), 1)
local title = Instance.new("TextLabel")
title.Name = "Title"
title.BackgroundTransparency = 1
title.Position = UDim2.fromOffset(12, 8)
title.Size = UDim2.new(1, -48, 0, 22)
title.Font = Enum.Font.GothamBold
title.TextSize = 16
title.TextXAlignment = Enum.TextXAlignment.Left
title.TextColor3 = Color3.fromRGB(240, 240, 245)
title.Text = "Drone ESP"
title.Parent = panel
local hideBtn = Instance.new("TextButton")
hideBtn.Name = "Hide"
hideBtn.Size = UDim2.fromOffset(28, 28)
hideBtn.Position = UDim2.new(1, -36, 0, 6)
hideBtn.BackgroundColor3 = Color3.fromRGB(45, 48, 58)
hideBtn.Text = "–"
hideBtn.Font = Enum.Font.GothamBold
hideBtn.TextSize = 18
hideBtn.TextColor3 = Color3.fromRGB(220, 220, 230)
hideBtn.AutoButtonColor = true
hideBtn.Parent = panel
makeCorner(hideBtn, 6)
statusLabel = Instance.new("TextLabel")
statusLabel.Name = "Status"
statusLabel.BackgroundTransparency = 1
statusLabel.Position = UDim2.fromOffset(12, 34)
statusLabel.Size = UDim2.new(1, -24, 0, 18)
statusLabel.Font = Enum.Font.Gotham
statusLabel.TextSize = 13
statusLabel.TextXAlignment = Enum.TextXAlignment.Left
statusLabel.Text = "OFF"
statusLabel.Parent = panel
toggleBtn = Instance.new("TextButton")
toggleBtn.Name = "Toggle"
toggleBtn.Size = UDim2.new(1, -24, 0, 34)
toggleBtn.Position = UDim2.fromOffset(12, 58)
toggleBtn.Font = Enum.Font.GothamBold
toggleBtn.TextSize = 15
toggleBtn.TextColor3 = Color3.fromRGB(255, 255, 255)
toggleBtn.AutoButtonColor = true
toggleBtn.Parent = panel
makeCorner(toggleBtn, 8)
local hint = Instance.new("TextLabel")
hint.Name = "Hint"
hint.BackgroundTransparency = 1
hint.Position = UDim2.fromOffset(12, 98)
hint.Size = UDim2.new(1, -24, 0, 18)
hint.Font = Enum.Font.Gotham
hint.TextSize = 11
hint.TextXAlignment = Enum.TextXAlignment.Left
hint.TextColor3 = Color3.fromRGB(140, 145, 160)
hint.Text = "Красный=BOT Синий=PLAYER"
hint.Parent = panel
-- collapsed open chip
local openBtn = Instance.new("TextButton")
openBtn.Name = "OpenChip"
openBtn.Visible = false
openBtn.Size = UDim2.fromOffset(110, 32)
openBtn.Position = UDim2.new(0, 16, 0.35, 0)
openBtn.BackgroundColor3 = Color3.fromRGB(22, 24, 30)
openBtn.BackgroundTransparency = 0.12
openBtn.Font = Enum.Font.GothamBold
openBtn.TextSize = 13
openBtn.TextColor3 = Color3.fromRGB(240, 240, 245)
openBtn.Text = "Drone ESP"
openBtn.AutoButtonColor = true
openBtn.Parent = gui
makeCorner(openBtn, 8)
makeStroke(openBtn, Color3.fromRGB(70, 80, 100), 1)
table.insert(guiConns, toggleBtn.MouseButton1Click:Connect(function()
setEspEnabled(not espEnabled)
end))
table.insert(guiConns, hideBtn.MouseButton1Click:Connect(function()
panel.Visible = false
openBtn.Visible = true
end))
table.insert(guiConns, openBtn.MouseButton1Click:Connect(function()
openBtn.Visible = false
panel.Visible = true
end))
-- drag panel
local dragging = false
local dragStart: Vector2? = nil
local startPos: UDim2? = nil
table.insert(guiConns, panel.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1
or input.UserInputType == Enum.UserInputType.Touch then
dragging = true
dragStart = input.Position
startPos = panel.Position
end
end))
table.insert(guiConns, UserInputService.InputChanged:Connect(function(input)
if not dragging or not dragStart or not startPos then
return
end
if input.UserInputType == Enum.UserInputType.MouseMovement
or input.UserInputType == Enum.UserInputType.Touch then
local delta = input.Position - dragStart
panel.Position = UDim2.new(
startPos.X.Scale,
startPos.X.Offset + delta.X,
startPos.Y.Scale,
startPos.Y.Offset + delta.Y
)
openBtn.Position = panel.Position
end
end))
table.insert(guiConns, UserInputService.InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1
or input.UserInputType == Enum.UserInputType.Touch then
dragging = false
end
end))
refreshGui()
end
local function destroyAll()
setEspEnabled(false)
stopUpdate()
disconnectFolderHooks()
clearAllTracked()
destroyGui()
_G.UAI_StopDroneESP = nil
_G.UAI_DestroyDroneESP = nil
_G.UAI_SetDroneESP = nil
print("[UAI] Drone ESP + GUI destroyed")
end
_G.UAI_StopDroneESP = function()
setEspEnabled(false)
print("[UAI] Drone ESP stopped (GUI remains)")
end
_G.UAI_SetDroneESP = setEspEnabled
_G.UAI_DestroyDroneESP = destroyAll
createGui()
setEspEnabled(true)
local total, bots, players = countTracked()
print(string.format(
"[UAI] Drone ESP GUI ready — ON, %d (%d BOT / %d PLAYER). Destroy: _G.UAI_DestroyDroneESP()",
total,
bots,
players
))
return string.format("GUI ready, ESP ON: %d (%d bot / %d player)", total, bots, players)No comments yet for this script.



