-- ===================================================== -- HABILIDAD ESPIA: Tablet + Nanobot con cara de camara -- 1) Equipa la "Spy Tablet" del inventario (se abre la lista de jugadores) -- 2) Elige un jugador: el nanobot vuela hasta su cabeza y entra en ella -- 3) Ves por sus ojos. "Players" para cambiar de jugador, "Exit" para salir -- ===================================================== local Players = game:GetService("Players") local RS = game:GetService("RunService") local TS = game:GetService("TweenService") local lp = Players.LocalPlayer local genv = (getgenv and getgenv()) or _G if genv.SpyOff then pcall(genv.SpyOff) end -- ===== ajustes ===== local BOT_SPEED = 70 -- velocidad del nanobot local BOT_COLOR = Color3.fromRGB(90, 200, 255) local FOV_SPY = 80 -- campo de vision al espiar local function new(class, props, parent) local o = Instance.new(class) for k, v in pairs(props) do o[k] = v end o.Parent = parent return o end local fxFolder = new("Folder", {Name = "SpyFX"}, workspace) local fov0 = workspace.CurrentCamera.FieldOfView local state = "idle" -- idle / flying / entering / spying / returning local target = nil local tool = nil local bot = nil local conns = {} local saved = nil local hiddenOrig = {} local hiddenChar = nil -- ===== interfaz ===== local gui = new("ScreenGui", {Name = "SpyGui", ResetOnSpawn = false, DisplayOrder = 999}, nil) pcall(function() gui.Parent = lp:WaitForChild("PlayerGui", 5) end) if not gui.Parent then pcall(function() gui.Parent = gethui() end) end if not gui.Parent then pcall(function() gui.Parent = game:GetService("CoreGui") end) end local toastLbl = new("TextLabel", { AnchorPoint = Vector2.new(0.5, 0), Position = UDim2.new(0.5, 0, 0, 60), Size = UDim2.new(0, 300, 0, 34), BackgroundColor3 = Color3.new(0, 0, 0), BackgroundTransparency = 0.35, TextColor3 = Color3.new(1, 1, 1), Font = Enum.Font.GothamBold, TextSize = 14, TextWrapped = true, Visible = false, BorderSizePixel = 0, Text = "", }, gui) local function toast(txt, dur) toastLbl.Text = txt toastLbl.Visible = true task.delay(dur or 3, function() if toastLbl.Text == txt then toastLbl.Visible = false end end) end -- panel de la tablet (lista de jugadores) local panel = new("Frame", { Position = UDim2.new(0, 20, 0.5, -150), Size = UDim2.new(0, 250, 0, 300), BackgroundColor3 = Color3.fromRGB(14, 18, 28), BorderSizePixel = 0, Visible = false, Active = true, }, gui) new("UICorner", {CornerRadius = UDim.new(0.04, 0)}, panel) new("UIStroke", {Color = BOT_COLOR, Thickness = 2}, panel) new("TextLabel", { Size = UDim2.new(1, 0, 0, 30), BackgroundTransparency = 1, Text = "SPY TABLET", TextColor3 = BOT_COLOR, Font = Enum.Font.GothamBold, TextSize = 16, }, panel) local list = new("ScrollingFrame", { Position = UDim2.new(0, 8, 0, 34), Size = UDim2.new(1, -16, 1, -80), BackgroundTransparency = 1, ScrollBarThickness = 4, BorderSizePixel = 0, CanvasSize = UDim2.new(0, 0, 0, 0), AutomaticCanvasSize = Enum.AutomaticSize.Y, }, panel) new("UIListLayout", {Padding = UDim.new(0, 4)}, list) local closeP = new("TextButton", { Position = UDim2.new(0, 8, 1, -40), Size = UDim2.new(1, -16, 0, 32), Text = "Cerrar", BackgroundColor3 = Color3.fromRGB(150, 40, 40), TextColor3 = Color3.new(1, 1, 1), Font = Enum.Font.GothamBold, TextSize = 14, BorderSizePixel = 0, }, panel) -- pantalla del espia (mientras ves por la camara) local hud = new("Frame", {Size = UDim2.new(1, 0, 1, 0), BackgroundTransparency = 1, Visible = false}, gui) new("UIStroke", {Color = BOT_COLOR, Thickness = 5, Transparency = 0.3}, hud) local rec = new("TextLabel", { Position = UDim2.new(0, 16, 0, 12), Size = UDim2.new(0, 260, 0, 24), BackgroundTransparency = 1, TextXAlignment = Enum.TextXAlignment.Left, TextColor3 = Color3.fromRGB(255, 90, 90), Font = Enum.Font.GothamBold, TextSize = 16, Text = "", }, hud) local function hudBtn(text, x, color) return new("TextButton", { AnchorPoint = Vector2.new(1, 0), Position = UDim2.new(1, x, 0, 12), Size = UDim2.new(0, 90, 0, 34), Text = text, BackgroundColor3 = color, TextColor3 = Color3.new(1, 1, 1), Font = Enum.Font.GothamBold, TextSize = 14, BorderSizePixel = 0, }, hud) end local swBtn = hudBtn("Players", -112, Color3.fromRGB(40, 110, 160)) local exitBtn = hudBtn("Exit", -16, Color3.fromRGB(170, 40, 40)) local flash = new("Frame", {Size = UDim2.new(1, 0, 1, 0), BackgroundColor3 = Color3.new(1, 1, 1), BackgroundTransparency = 1, BorderSizePixel = 0, ZIndex = 5}, hud) -- ===== nanobot con cara de camara ===== local function makeBot() local m = Instance.new("Model") local parts = {} local function add(size, shape, color, neon, pos, rot, spin) local p = Instance.new("Part") if shape then p.Shape = shape end p.Size = size p.Color = color p.Material = neon and Enum.Material.Neon or Enum.Material.Metal p.Anchored = true p.CanCollide = false p.CanQuery = false p.CanTouch = false p.CastShadow = false p.Parent = m table.insert(parts, {part = p, size = size, pos = pos, rot = rot, spin = spin}) return p end local CYL, BALL = Enum.PartType.Cylinder, Enum.PartType.Ball local AX = CFrame.Angles(0, math.rad(90), 0) -- cilindro apuntando al frente local AY = CFrame.Angles(0, 0, math.rad(90)) -- cilindro vertical local body = add(Vector3.new(1.5, 1.5, 1.5), BALL, Color3.fromRGB(70, 75, 90), false, Vector3.new(0, 0, 0), CFrame.new(), false) add(Vector3.new(0.3, 1, 1), CYL, Color3.fromRGB(12, 12, 16), false, Vector3.new(0, 0, -0.65), AX, false) add(Vector3.new(0.12, 0.6, 0.6), CYL, BOT_COLOR, true, Vector3.new(0, 0, -0.82), AX, false) local halo = add(Vector3.new(0.1, 2.3, 2.3), CYL, BOT_COLOR, true, Vector3.new(0, 0, 0), AY, true) halo.Transparency = 0.4 add(Vector3.new(0.12, 0.8, 0.12), nil, Color3.fromRGB(190, 195, 210), false, Vector3.new(0, 1, 0.1), CFrame.new(), false) add(Vector3.new(0.3, 0.3, 0.3), BALL, BOT_COLOR, true, Vector3.new(0, 1.45, 0.1), CFrame.new(), false) m.PrimaryPart = body m.Parent = fxFolder local a0 = new("Attachment", {Position = Vector3.new(0, 0.4, 0.6)}, body) local a1 = new("Attachment", {Position = Vector3.new(0, -0.4, 0.6)}, body) new("Trail", { Attachment0 = a0, Attachment1 = a1, Lifetime = 0.35, LightEmission = 1, Color = ColorSequence.new(BOT_COLOR), Transparency = NumberSequence.new({NumberSequenceKeypoint.new(0, 0.2), NumberSequenceKeypoint.new(1, 1)}), }, body) new("PointLight", {Color = BOT_COLOR, Range = 14, Brightness = 2}, body) return {model = m, parts = parts} end local function placeBot(b, cf, scale, t) for _, e in ipairs(b.parts) do local rot = e.rot if e.spin then rot = CFrame.Angles(0, t * 9, 0) * e.rot end e.part.Size = e.size * scale e.part.CFrame = cf * CFrame.new(e.pos * scale) * rot end end local function flyBot(b, startPos, getDest, onDone) local pos = startPos local t0 = os.clock() local con con = RS.Heartbeat:Connect(function(dt) local dest = getDest() if not dest then con:Disconnect() onDone(false) return end local d = dest - pos local dist = d.Magnitude if dist < 1.2 then con:Disconnect() onDone(true) return end local dir = d.Unit pos = pos + dir * math.min(BOT_SPEED * dt, dist) local tt = os.clock() - t0 local wob = Vector3.new(0, math.sin(tt * 9) * 0.5, 0) placeBot(b, CFrame.new(pos + wob, pos + wob + dir), 1, tt) end) table.insert(conns, con) return con end local function shrinkBot(b, pos, onDone) local t0 = os.clock() local con con = RS.Heartbeat:Connect(function() local k = (os.clock() - t0) / 0.35 if k >= 1 then con:Disconnect() onDone() return end placeBot(b, CFrame.new(pos), math.max(1 - k, 0.05), os.clock()) end) table.insert(conns, con) end local function burst(pos) local p = new("Part", {Anchored = true, CanCollide = false, CanQuery = false, Transparency = 1, Size = Vector3.new(1, 1, 1), Position = pos}, fxFolder) local e = new("ParticleEmitter", { Color = ColorSequence.new(BOT_COLOR), LightEmission = 1, Rate = 0, Lifetime = NumberRange.new(0.4, 0.8), Speed = NumberRange.new(8, 20), SpreadAngle = Vector2.new(180, 180), Size = NumberSequence.new({NumberSequenceKeypoint.new(0, 0.6), NumberSequenceKeypoint.new(1, 0)}), }, p) e:Emit(40) task.delay(1.5, function() p:Destroy() end) end -- ===== ver por los ojos del jugador ===== local function hideTarget(ch, on) if not ch then return end for _, d in ipairs(ch:GetDescendants()) do if d:IsA("Decal") and d.Parent and d.Parent.Name == "Head" then if on then hiddenOrig[d] = d.Transparency d.Transparency = 1 elseif hiddenOrig[d] ~= nil then d.Transparency = hiddenOrig[d] hiddenOrig[d] = nil end elseif d:IsA("BasePart") and (d.Name == "Head" or (d.Parent and d.Parent:IsA("Accoutrement"))) then d.LocalTransparencyModifier = on and 1 or 0 end end end local function freeze(on) local hum = lp.Character and lp.Character:FindFirstChildOfClass("Humanoid") if not hum then saved = nil return end if on then saved = saved or {ws = hum.WalkSpeed, jp = hum.JumpPower, jh = hum.JumpHeight} hum.WalkSpeed = 0 hum.JumpPower = 0 hum.JumpHeight = 0 elseif saved then hum.WalkSpeed = saved.ws hum.JumpPower = saved.jp hum.JumpHeight = saved.jh saved = nil end end local function stopSpyView() pcall(function() RS:UnbindFromRenderStep("SpyCam") end) hideTarget(hiddenChar, false) hiddenChar = nil local cam = workspace.CurrentCamera cam.CameraType = Enum.CameraType.Custom local hum = lp.Character and lp.Character:FindFirstChildOfClass("Humanoid") if hum then cam.CameraSubject = hum end cam.FieldOfView = fov0 freeze(false) hud.Visible = false end local function startSpy() state = "spying" local cam = workspace.CurrentCamera cam.CameraType = Enum.CameraType.Scriptable cam.FieldOfView = FOV_SPY freeze(true) panel.Visible = false hud.Visible = true rec.Text = "REC " .. target.DisplayName flash.BackgroundTransparency = 0.2 TS:Create(flash, TweenInfo.new(0.5), {BackgroundTransparency = 1}):Play() pcall(function() RS:UnbindFromRenderStep("SpyCam") end) RS:BindToRenderStep("SpyCam", Enum.RenderPriority.Camera.Value + 1, function() local ch = target and target.Character if ch ~= hiddenChar then hideTarget(hiddenChar, false) hiddenChar = ch hideTarget(ch, true) end local head = ch and ch:FindFirstChild("Head") if head then cam.CFrame = head.CFrame * CFrame.new(0, 0.2, -0.9) end end) end local function exitSpy(msg) if state ~= "spying" then return end local head = target and target.Character and target.Character:FindFirstChild("Head") local from = head and head.Position stopSpyView() target = nil if msg then toast(msg, 3) end if not from then state = "idle" return end state = "returning" local b = makeBot() bot = b flyBot(b, from, function() local h = lp.Character and lp.Character:FindFirstChild("Head") return h and h.Position end, function() b.model:Destroy() bot = nil state = "idle" end) end -- ===== enviar el nanobot ===== local function launch(p) if state == "flying" or state == "entering" or state == "returning" then toast("El nanobot esta ocupado", 2) return end local ch = p.Character if not (ch and ch:FindFirstChild("Head")) then toast(p.DisplayName .. " no tiene personaje", 2) return end local startPos = nil if state == "spying" then local oh = target and target.Character and target.Character:FindFirstChild("Head") startPos = oh and oh.Position stopSpyView() end if not startPos then local lh = lp.Character and lp.Character:FindFirstChild("Head") if not lh then toast("Sin personaje", 2) return end startPos = lh.Position + Vector3.new(0, 1.5, 0) end target = p state = "flying" panel.Visible = false toast("Nanobot enviado a " .. p.DisplayName, 3) local b = makeBot() bot = b flyBot(b, startPos, function() local h = target and target.Character and target.Character:FindFirstChild("Head") return h and h.Position end, function(ok) if not ok then b.model:Destroy() bot = nil state = "idle" target = nil toast("Se perdio la senal del jugador", 3) return end state = "entering" local h = target.Character and target.Character:FindFirstChild("Head") local hp = h and h.Position or startPos burst(hp) shrinkBot(b, hp, function() b.model:Destroy() bot = nil if target and target.Character and target.Character:FindFirstChild("Head") then startSpy() else state = "idle" target = nil toast("Se perdio la senal del jugador", 3) end end) end) end -- ===== lista de jugadores ===== local function refreshList() for _, c in ipairs(list:GetChildren()) do if c:IsA("TextButton") then c:Destroy() end end for _, p in ipairs(Players:GetPlayers()) do if p ~= lp then local b = new("TextButton", { Size = UDim2.new(1, -6, 0, 34), Text = p.DisplayName .. " (@" .. p.Name .. ")", BackgroundColor3 = Color3.fromRGB(28, 36, 52), TextColor3 = Color3.new(1, 1, 1), Font = Enum.Font.Gotham, TextSize = 13, BorderSizePixel = 0, TextTruncate = Enum.TextTruncate.AtEnd, }, list) b.MouseButton1Click:Connect(function() launch(p) end) end end end local function setPanel(v) panel.Visible = v if v then refreshList() end end closeP.MouseButton1Click:Connect(function() setPanel(false) end) swBtn.MouseButton1Click:Connect(function() setPanel(true) end) exitBtn.MouseButton1Click:Connect(function() exitSpy() end) table.insert(conns, Players.PlayerAdded:Connect(function() if panel.Visible then refreshList() end end)) table.insert(conns, Players.PlayerRemoving:Connect(function(p) if p == target and state == "spying" then exitSpy("El jugador salio del juego") end task.defer(function() if panel.Visible then refreshList() end end) end)) -- ===== la tablet en el inventario ===== local function makeTool() local t = new("Tool", {Name = "Spy Tablet", CanBeDropped = false, RequiresHandle = true, ToolTip = "Spy Tablet"}, nil) local h = new("Part", {Name = "Handle", Size = Vector3.new(1.6, 0.18, 1.1), Color = Color3.fromRGB(25, 28, 36), Material = Enum.Material.SmoothPlastic, CanCollide = false}, t) local s = new("Part", {Name = "Screen", Size = Vector3.new(1.4, 0.04, 0.9), Color = BOT_COLOR, Material = Enum.Material.Neon, CanCollide = false, Massless = true}, t) s.CFrame = h.CFrame * CFrame.new(0, 0.11, 0) new("WeldConstraint", {Part0 = h, Part1 = s}, h) t.Equipped:Connect(function() setPanel(true) end) t.Unequipped:Connect(function() setPanel(false) end) t.Activated:Connect(function() setPanel(not panel.Visible) end) return t end local function ensureTool() if tool and tool.Parent then return end local bp = lp:FindFirstChildOfClass("Backpack") or lp:WaitForChild("Backpack", 5) if not bp then return end tool = makeTool() tool.Parent = bp end ensureTool() table.insert(conns, lp.CharacterAdded:Connect(function() if state == "spying" then stopSpyView() target = nil state = "idle" end task.wait(1) ensureTool() end)) -- ===== cerrar todo ===== genv.SpyOff = function() for _, c in ipairs(conns) do pcall(function() c:Disconnect() end) end pcall(stopSpyView) pcall(function() if tool then tool:Destroy() end end) pcall(function() fxFolder:Destroy() end) pcall(function() gui:Destroy() end) end toast("Spy Tablet lista: equipala desde tu inventario", 4)