hello everyone, today the script is on
Key Required

hello everyone, today the script is on

PANTSIRwwwww21312wwwww21312 750 views 987 executesUpdated Sep 23, 2026
Unrated
00
Lua Script•577 lines (14574 chars)
--[[
  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)

Features & Information

In this script there is only one function to see drones and to see a bot is it flying or a human

Community Comments (0)

No comments yet for this script.

More Scripts for PANTSIR