local Players = game:GetService("Players") local RunService = game:GetService("RunService") local UserInputService = game:GetService("UserInputService") local Lighting = game:GetService("Lighting") local player = Players.LocalPlayer local playerGui = player:WaitForChild("PlayerGui") -- Elimina copias viejas del menú local viejo = playerGui:FindFirstChild("VolarGui") if viejo then viejo:Destroy() end -- ========= AJUSTES ========= local VEL_MIN, VEL_MAX = 10, 500 local ajustes = { velVuelo = 60, caminar = 16, salto = 50, fov = 70 } local tocado = { caminar = false, salto = false } local POS_PANEL = UDim2.new(0, 70, 0.5, -140) local POS_BOTON = UDim2.new(0, 10, 0.5, -24) -- ========= ESTADO ========= local volando, noclip, saltoInfinito = false, false, false local subiendo, bajando = false, false local velActual = Vector3.zero local conexionVuelo, linearVel, alignOri, attachment local posGuardada = nil local gravedadOriginal = workspace.Gravity local luzOriginal = { Brightness = Lighting.Brightness, ClockTime = Lighting.ClockTime, FogEnd = Lighting.FogEnd, Ambient = Lighting.Ambient, GlobalShadows = Lighting.GlobalShadows, } local function getPersonaje() local c = player.Character local h = c and c:FindFirstChildOfClass("Humanoid") local r = c and c:FindFirstChild("HumanoidRootPart") return c, h, r end local function esPuntero(input) return input.UserInputType == Enum.UserInputType.Touch or input.UserInputType == Enum.UserInputType.MouseButton1 end -- ========= INTERFAZ BASE ========= local gui = Instance.new("ScreenGui") gui.Name = "VolarGui" gui.ResetOnSpawn = false gui.IgnoreGuiInset = true gui.DisplayOrder = 100 gui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling gui.Parent = playerGui local ROJO = Color3.fromRGB(200, 60, 60) local VERDE = Color3.fromRGB(60, 180, 90) local GRIS = Color3.fromRGB(70, 70, 85) local OSCURO = Color3.fromRGB(30, 30, 35) local AZUL = Color3.fromRGB(70, 110, 220) local function redondear(obj, r) local c = Instance.new("UICorner") c.CornerRadius = UDim.new(0, r) c.Parent = obj end local function crearBoton(padre, texto, color, size) local b = Instance.new("TextButton") b.Size = size b.BackgroundColor3 = color b.TextColor3 = Color3.new(1, 1, 1) b.Font = Enum.Font.GothamBold b.TextScaled = true b.Text = texto b.Parent = padre local lim = Instance.new("UITextSizeConstraint") lim.MaxTextSize = 16 lim.Parent = b redondear(b, 8) return b end -- Aviso corto arriba de la pantalla local aviso = Instance.new("TextLabel") aviso.AnchorPoint = Vector2.new(0.5, 0) aviso.Position = UDim2.new(0.5, 0, 0, 8) aviso.Size = UDim2.new(0, 260, 0, 28) aviso.BackgroundColor3 = OSCURO aviso.BackgroundTransparency = 0.15 aviso.TextColor3 = Color3.new(1, 1, 1) aviso.Font = Enum.Font.GothamBold aviso.TextScaled = true aviso.Visible = false aviso.Parent = gui redondear(aviso, 8) local avisoId = 0 local function avisar(texto) avisoId += 1 local mi = avisoId aviso.Text = " " .. texto .. " " aviso.Visible = true task.delay(2.2, function() if mi == avisoId then aviso.Visible = false end end) end -- ========= BOTÓN ✈ (siempre visible) ========= local abrir = Instance.new("TextButton") abrir.Size = UDim2.new(0, 48, 0, 48) abrir.Position = POS_BOTON abrir.BackgroundColor3 = OSCURO abrir.BackgroundTransparency = 0.1 abrir.TextColor3 = Color3.new(1, 1, 1) abrir.Font = Enum.Font.GothamBold abrir.TextScaled = true abrir.Text = "✈" abrir.ZIndex = 5 abrir.Parent = gui redondear(abrir, 24) -- ========= PANEL ========= local panel = Instance.new("Frame") panel.Size = UDim2.new(0, 190, 0, 0) panel.AutomaticSize = Enum.AutomaticSize.Y panel.Position = POS_PANEL panel.BackgroundColor3 = OSCURO panel.BackgroundTransparency = 0.08 panel.BorderSizePixel = 0 panel.Active = true panel.Visible = true panel.Parent = gui redondear(panel, 10) local pad = Instance.new("UIPadding") pad.PaddingTop, pad.PaddingBottom = UDim.new(0, 6), UDim.new(0, 6) pad.PaddingLeft, pad.PaddingRight = UDim.new(0, 6), UDim.new(0, 6) pad.Parent = panel local listaPanel = Instance.new("UIListLayout") listaPanel.Padding = UDim.new(0, 5) listaPanel.SortOrder = Enum.SortOrder.LayoutOrder listaPanel.Parent = panel -- Cabecera local cabecera = Instance.new("Frame") cabecera.Size = UDim2.new(1, 0, 0, 30) cabecera.BackgroundTransparency = 1 cabecera.LayoutOrder = 1 cabecera.Parent = panel local barra = Instance.new("TextLabel") barra.Size = UDim2.new(1, -38, 1, 0) barra.BackgroundColor3 = Color3.fromRGB(50, 50, 60) barra.TextColor3 = Color3.new(1, 1, 1) barra.Font = Enum.Font.GothamBold barra.TextScaled = true barra.Text = "≡ Mantené y mové" barra.Active = true barra.Parent = cabecera redondear(barra, 8) local limBarra = Instance.new("UITextSizeConstraint") limBarra.MaxTextSize = 14 limBarra.Parent = barra local botonCerrar = crearBoton(cabecera, "✕", ROJO, UDim2.new(0, 32, 1, 0)) botonCerrar.Position = UDim2.new(1, -32, 0, 0) -- Pestañas local filaTabs = Instance.new("Frame") filaTabs.Size = UDim2.new(1, 0, 0, 30) filaTabs.BackgroundTransparency = 1 filaTabs.LayoutOrder = 2 filaTabs.Parent = panel local nombresTabs = { "Vuelo", "Mover", "Extra" } local botonesTab, paginas = {}, {} for i, nombre in ipairs(nombresTabs) do local b = crearBoton(filaTabs, nombre, GRIS, UDim2.new(0.32, 0, 1, 0)) b.Position = UDim2.new((i - 1) * 0.34, 0, 0, 0) botonesTab[i] = b local pg = Instance.new("Frame") pg.Size = UDim2.new(1, 0, 0, 0) pg.AutomaticSize = Enum.AutomaticSize.Y pg.BackgroundTransparency = 1 pg.LayoutOrder = 3 pg.Visible = (i == 1) pg.Parent = panel local lp = Instance.new("UIListLayout") lp.Padding = UDim.new(0, 5) lp.SortOrder = Enum.SortOrder.LayoutOrder lp.Parent = pg paginas[i] = pg end local function elegirTab(n) for i = 1, #paginas do paginas[i].Visible = (i == n) botonesTab[i].BackgroundColor3 = (i == n) and AZUL or GRIS end end for i, b in ipairs(botonesTab) do b.Activated:Connect(function() elegirTab(i) end) end elegirTab(1) -- ========= COMPONENTES ========= local function repetirAlMantener(boton, fn) boton.InputBegan:Connect(function(input) if not esPuntero(input) then return end local activo = true input.Changed:Connect(function() if input.UserInputState == Enum.UserInputState.End then activo = false end end) fn() task.spawn(function() task.wait(0.4) while activo do fn() task.wait(0.07) end end) end) end local function crearStepper(padre, nombre, valor, min, max, paso, alCambiar) local fila = Instance.new("Frame") fila.Size = UDim2.new(1, 0, 0, 36) fila.BackgroundTransparency = 1 fila.Parent = padre local menos = crearBoton(fila, "-", GRIS, UDim2.new(0.24, 0, 1, 0)) local mas = crearBoton(fila, "+", GRIS, UDim2.new(0.24, 0, 1, 0)) mas.Position = UDim2.new(0.76, 0, 0, 0) local etiqueta = Instance.new("TextLabel") etiqueta.Size = UDim2.new(0.5, 0, 1, 0) etiqueta.Position = UDim2.new(0.25, 0, 0, 0) etiqueta.BackgroundTransparency = 1 etiqueta.TextColor3 = Color3.new(1, 1, 1) etiqueta.Font = Enum.Font.GothamBold etiqueta.TextScaled = true etiqueta.Parent = fila local lim = Instance.new("UITextSizeConstraint") lim.MaxTextSize = 14 lim.Parent = etiqueta local function mostrar() etiqueta.Text = nombre .. " " .. valor end local function cambiar(d) valor = math.clamp(valor + d, min, max) mostrar() alCambiar(valor) end mostrar() repetirAlMantener(menos, function() cambiar(-paso) end) repetirAlMantener(mas, function() cambiar(paso) end) end local function crearToggle(padre, nombre, alCambiar) local estado = false local b = crearBoton(padre, nombre .. ": OFF", ROJO, UDim2.new(1, 0, 0, 36)) local obj = {} function obj.set(v) estado = v b.Text = nombre .. (v and ": ON" or ": OFF") b.BackgroundColor3 = v and VERDE or ROJO alCambiar(v) end function obj.get() return estado end b.Activated:Connect(function() obj.set(not estado) end) return obj end -- ========= ARRASTRE ========= local function hacerArrastrable(manejador, objetivo, limitar) local arrastrando, input0, inicio, posAbs = false, nil, nil, nil local info = { movido = false } manejador.InputBegan:Connect(function(input) if esPuntero(input) then arrastrando = true info.movido = false input0 = input inicio = input.Position posAbs = objetivo.AbsolutePosition input.Changed:Connect(function() if input.UserInputState == Enum.UserInputState.End then arrastrando = false end end) end end) UserInputService.InputChanged:Connect(function(input) if arrastrando and (input == input0 or input.UserInputType == Enum.UserInputType.MouseMovement) then local d = input.Position - inicio if d.Magnitude > 10 then info.movido = true end if info.movido then local x, y = posAbs.X + d.X, posAbs.Y + d.Y if limitar then local vp = workspace.CurrentCamera.ViewportSize x = math.clamp(x, 0, vp.X - objetivo.AbsoluteSize.X) y = math.clamp(y, 0, vp.Y - objetivo.AbsoluteSize.Y) end objetivo.Position = UDim2.fromOffset(x, y) end end end) return info end local infoPanel = hacerArrastrable(barra, panel, false) local infoAbrir = hacerArrastrable(abrir, abrir, true) local function mostrarPanel(v) panel.Visible = v if v then local c = panel.AbsolutePosition + panel.AbsoluteSize / 2 local vp = workspace.CurrentCamera.ViewportSize if c.X < 0 or c.X > vp.X or c.Y < 0 or c.Y > vp.Y then panel.Position = POS_PANEL end end end abrir.Activated:Connect(function() if infoAbrir.movido then infoAbrir.movido = false return end mostrarPanel(not panel.Visible) end) botonCerrar.Activated:Connect(function() mostrarPanel(false) end) -- ========= BOTONES FLOTANTES ▲ ▼ ========= local function crearFlotante(texto, posY) local b = Instance.new("TextButton") b.AnchorPoint = Vector2.new(1, 0.5) b.Size = UDim2.new(0, 64, 0, 64) b.Position = UDim2.new(1, -20, 0.5, posY) b.BackgroundColor3 = OSCURO b.BackgroundTransparency = 0.25 b.TextColor3 = Color3.new(1, 1, 1) b.Font = Enum.Font.GothamBold b.TextScaled = true b.Text = texto b.Visible = false b.Parent = gui redondear(b, 32) return b end local flotanteSubir = crearFlotante("▲", -42) local flotanteBajar = crearFlotante("▼", 42) local function mantener(boton, setter) boton.InputBegan:Connect(function(input) if esPuntero(input) then setter(true) input.Changed:Connect(function() if input.UserInputState == Enum.UserInputState.End then setter(false) end end) end end) end mantener(flotanteSubir, function(v) subiendo = v end) mantener(flotanteBajar, function(v) bajando = v end) -- ========= VUELO ========= local volarToggle local function limpiarVuelo() if conexionVuelo then conexionVuelo:Disconnect() conexionVuelo = nil end if linearVel then linearVel:Destroy() linearVel = nil end if alignOri then alignOri:Destroy() alignOri = nil end if attachment then attachment:Destroy() attachment = nil end velActual = Vector3.zero end local function detenerVuelo() volando = false subiendo, bajando = false, false flotanteSubir.Visible = false flotanteBajar.Visible = false limpiarVuelo() local _, humanoid = getPersonaje() if humanoid then humanoid.PlatformStand = false end end local function empezarVuelo() local _, humanoid, raiz = getPersonaje() if not humanoid or not raiz or humanoid.Health <= 0 then return false end limpiarVuelo() volando = true flotanteSubir.Visible = true flotanteBajar.Visible = true humanoid.PlatformStand = true attachment = Instance.new("Attachment") attachment.Parent = raiz linearVel = Instance.new("LinearVelocity") linearVel.Attachment0 = attachment linearVel.MaxForce = math.huge linearVel.VelocityConstraintMode = Enum.VelocityConstraintMode.Vector linearVel.VectorVelocity = Vector3.zero linearVel.Parent = raiz alignOri = Instance.new("AlignOrientation") alignOri.Mode = Enum.OrientationAlignmentMode.OneAttachment alignOri.Attachment0 = attachment alignOri.RigidityEnabled = false alignOri.MaxTorque = math.huge alignOri.Responsiveness = 25 alignOri.Parent = raiz conexionVuelo = RunService.RenderStepped:Connect(function(dt) local camara = workspace.CurrentCamera local dir = humanoid.MoveDirection local objetivo = Vector3.zero local vel = ajustes.velVuelo if dir.Magnitude > 0.05 then local rel = camara.CFrame:VectorToObjectSpace(dir) local v = camara.CFrame.LookVector * -rel.Z + camara.CFrame.RightVector * rel.X if v.Magnitude > 0.001 then objetivo = v.Unit * math.min(dir.Magnitude, 1) * vel end end if subiendo or humanoid.Jump then objetivo += Vector3.yAxis * vel * 0.7 end if bajando then objetivo -= Vector3.yAxis * vel * 0.7 end velActual = velActual:Lerp(objetivo, math.clamp(dt * 8, 0, 1)) linearVel.VectorVelocity = velActual local look = camara.CFrame.LookVector local yaw = math.atan2(-look.X, -look.Z) local inclinacion = math.clamp(velActual.Magnitude / math.max(vel, 1), 0, 1) * math.rad(25) alignOri.CFrame = CFrame.Angles(0, yaw, 0) * CFrame.Angles(-inclinacion, 0, 0) end) return true end -- ========= PESTAÑA VUELO ========= volarToggle = crearToggle(paginas[1], "Volar", function(v) if v then if not empezarVuelo() then volarToggle.set(false) avisar("No se pudo volar ahora") end else detenerVuelo() end end) crearStepper(paginas[1], "Vuelo", ajustes.velVuelo, VEL_MIN, VEL_MAX, 10, function(v) ajustes.velVuelo = v end) crearToggle(paginas[1], "Noclip", function(v) noclip = v end) -- ========= PESTAÑA MOVER ========= local function aplicarMovimiento() local _, h = getPersonaje() if not h then return end if tocado.caminar then h.WalkSpeed = ajustes.caminar end if tocado.salto then h.UseJumpPower = true h.JumpPower = ajustes.salto end end crearStepper(paginas[2], "Caminar", ajustes.caminar, 4, 300, 4, function(v) ajustes.caminar = v tocado.caminar = true aplicarMovimiento() end) crearStepper(paginas[2], "Salto", ajustes.salto, 10, 300, 10, function(v) ajustes.salto = v tocado.salto = true aplicarMovimiento() end) crearToggle(paginas[2], "Salto infinito", function(v) saltoInfinito = v end) crearToggle(paginas[2], "Baja gravedad", function(v) workspace.Gravity = v and gravedadOriginal * 0.3 or gravedadOriginal end) -- ========= PESTAÑA EXTRA ========= local botonGuardar = crearBoton(paginas[3], "Guardar posición", AZUL, UDim2.new(1, 0, 0, 34)) local botonIr = crearBoton(paginas[3], "Ir a la posición", AZUL, UDim2.new(1, 0, 0, 34)) botonGuardar.Activated:Connect(function() local _, _, raiz = getPersonaje() if raiz then posGuardada = raiz.CFrame avisar("Posición guardada") end end) botonIr.Activated:Connect(function() local _, _, raiz = getPersonaje() if not posGuardada then avisar("Primero guardá una posición") return end if raiz then raiz.CFrame = posGuardada avisar("Teletransportado") end end) crearStepper(paginas[3], "FOV", ajustes.fov, 30, 120, 5, function(v) ajustes.fov = v workspace.CurrentCamera.FieldOfView = v end) crearToggle(paginas[3], "Brillo total", function(v) if v then Lighting.Brightness = 3 Lighting.ClockTime = 14 Lighting.FogEnd = 1e6 Lighting.Ambient = Color3.new(1, 1, 1) Lighting.GlobalShadows = false else for k, val in pairs(luzOriginal) do Lighting[k] = val end end end) local botonCentrar = crearBoton(paginas[3], "Centrar menú", GRIS, UDim2.new(1, 0, 0, 30)) botonCentrar.Activated:Connect(function() panel.Position = POS_PANEL abrir.Position = POS_BOTON end) -- ========= NOCLIP ========= RunService.Stepped:Connect(function() if not noclip then return end local personaje = player.Character if not personaje then return end for _, parte in ipairs(personaje:GetDescendants()) do if parte:IsA("BasePart") then parte.CanCollide = false end end end) -- ========= SALTO INFINITO ========= UserInputService.JumpRequest:Connect(function() if saltoInfinito and not volando then local _, humanoid = getPersonaje() if humanoid then humanoid:ChangeState(Enum.HumanoidStateType.Jumping) end end end) -- ========= REAPARICIÓN ========= local function alAparecer(personaje) volarToggle.set(false) local humanoid = personaje:WaitForChild("Humanoid", 10) if not humanoid then return end humanoid.Died:Connect(function() volarToggle.set(false) end) task.wait(0.2) aplicarMovimiento() end player.CharacterAdded:Connect(alAparecer) if player.Character then task.spawn(alAparecer, player.Character) end avisar("Menú de vuelo cargado ✈")