Spy GUI
Key RequiredUniversal

Spy GUI

Universal Scriptbob_coolbob_cool 449 views 1.5K executesUpdated Mar 19, 2026
Unrated
00
Lua Script•169 lines (4623 chars)
local player = game.Players.LocalPlayer
local playerGui = player:WaitForChild("PlayerGui")
local camera = workspace.CurrentCamera

-- 🪟 Main GUI
local gui = Instance.new("ScreenGui", playerGui)
gui.Name = "SPY_GUI"

-- 📦 Main Frame
local main = Instance.new("Frame", gui)
main.Size = UDim2.new(0, 200, 0, 120)
main.Position = UDim2.new(0, 20, 0.5, -60)
main.BackgroundColor3 = Color3.fromRGB(25,25,25)
main.Active = true
main.Draggable = true

-- 🎛 Buttons
local spectateBtn = Instance.new("TextButton", main)
spectateBtn.Size = UDim2.new(1, -10, 0, 40)
spectateBtn.Position = UDim2.new(0, 5, 0, 5)
spectateBtn.Text = "Spectate"

local rollBtn = Instance.new("TextButton", main)
rollBtn.Size = UDim2.new(1, -10, 0, 40)
rollBtn.Position = UDim2.new(0, 5, 0, 55)
rollBtn.Text = "ROLL!"

-- =========================
-- 👁️ SPECTATE SYSTEM (UPDATED)
-- =========================

local spectating = false
local currentTarget = nil

-- List Frame
local listFrame = Instance.new("Frame", gui)
listFrame.Size = UDim2.new(0, 250, 0, 300)
listFrame.Position = UDim2.new(0.5, -125, 0.5, -150)
listFrame.BackgroundColor3 = Color3.fromRGB(20,20,20)
listFrame.Visible = false
listFrame.Active = true
listFrame.Draggable = true

-- ❌ Close button
local closeBtn = Instance.new("TextButton", listFrame)
closeBtn.Size = UDim2.new(0, 30, 0, 30)
closeBtn.Position = UDim2.new(1, -35, 0, 5)
closeBtn.Text = "X"
closeBtn.BackgroundColor3 = Color3.fromRGB(255,0,0)

-- 📜 Player list
local scroll = Instance.new("ScrollingFrame", listFrame)
scroll.Size = UDim2.new(1, -10, 1, -80)
scroll.Position = UDim2.new(0, 5, 0, 40)
scroll.BackgroundColor3 = Color3.fromRGB(30,30,30)
scroll.BorderSizePixel = 0
scroll.AutomaticCanvasSize = Enum.AutomaticSize.Y

local layout = Instance.new("UIListLayout", scroll)
layout.SortOrder = Enum.SortOrder.LayoutOrder
layout.Padding = UDim.new(0, 5)

-- 🔄 Refresh button
local refreshBtn = Instance.new("TextButton", listFrame)
refreshBtn.Size = UDim2.new(1, -10, 0, 30)
refreshBtn.Position = UDim2.new(0, 5, 1, -35)
refreshBtn.Text = "Refresh"

-- 🛑 Stop Spectating
local stopBtn = Instance.new("TextButton", listFrame)
stopBtn.Size = UDim2.new(1, -10, 0, 30)
stopBtn.Position = UDim2.new(0, 5, 1, -70)
stopBtn.Text = "STOP SPECTATING"
stopBtn.BackgroundColor3 = Color3.fromRGB(255,0,0)
stopBtn.Visible = false

-- 🔁 Refresh list (NEW)
local function refreshList()
	for _, child in pairs(scroll:GetChildren()) do
		if child:IsA("TextButton") then
			child:Destroy()
		end
	end

	for _, plr in pairs(game.Players:GetPlayers()) do
		if plr ~= player then
			local btn = Instance.new("TextButton")
			btn.Size = UDim2.new(1, -5, 0, 30)
			btn.Text = plr.DisplayName .. " (@" .. plr.Name .. ")"
			btn.BackgroundColor3 = Color3.fromRGB(40,40,40)
			btn.TextColor3 = Color3.new(1,1,1)
			btn.Parent = scroll

			if currentTarget == plr then
				btn.BackgroundColor3 = Color3.fromRGB(0, 170, 255)
			end

			btn.MouseButton1Click:Connect(function()
				if plr.Character and plr.Character:FindFirstChild("Humanoid") then
					camera.CameraSubject = plr.Character.Humanoid
					currentTarget = plr
					stopBtn.Visible = true
					refreshList()
				end
			end)
		end
	end
end

-- Open list
spectateBtn.MouseButton1Click:Connect(function()
	listFrame.Visible = true
	refreshList()
end)

-- Close list
closeBtn.MouseButton1Click:Connect(function()
	listFrame.Visible = false
end)

-- Refresh button
refreshBtn.MouseButton1Click:Connect(refreshList)

-- Stop spectating
stopBtn.MouseButton1Click:Connect(function()
	camera.CameraSubject = player.Character:WaitForChild("Humanoid")
	currentTarget = nil
	stopBtn.Visible = false
	refreshList()
end)

-- Auto update list on join/leave
game.Players.PlayerAdded:Connect(refreshList)
game.Players.PlayerRemoving:Connect(refreshList)

-- =========================
-- 🤸 ROLL SYSTEM (UNCHANGED)
-- =========================

rollBtn.MouseButton1Click:Connect(function()
	local char = player.Character
	if not char then return end

	local humanoid = char:FindFirstChild("Humanoid")
	local root = char:FindFirstChild("HumanoidRootPart")

	if not humanoid or not root then return end

	-- Drop
	humanoid.Sit = true

	-- Spin + push forward
	local bv = Instance.new("BodyVelocity")
	bv.Velocity = root.CFrame.LookVector * 50 + Vector3.new(0,20,0)
	bv.MaxForce = Vector3.new(1e5,1e5,1e5)
	bv.Parent = root

	local spin = Instance.new("BodyAngularVelocity")
	spin.AngularVelocity = Vector3.new(10,0,0)
	spin.MaxTorque = Vector3.new(1e5,1e5,1e5)
	spin.Parent = root

	-- Cleanup after roll
	task.delay(1, function()
		bv:Destroy()
		spin:Destroy()
		humanoid.Sit = false
	end)
end)

Features & Information

Spectation, ROLL

Community Comments (2)

nikitakalitin2nikitakalitin2Mar 22, 2026

Maid by ai or yourself

Replying to @nikitakalitin2
bob_coolbob_coolApr 1, 2026

@nikitakalitin2 most parts were ai! i made scripts and the ai made the parts (the -- (emoji) name) idk how to tell!

More Scripts for Universal Scripts