Aim Assist
Key RequiredUniversal

Aim Assist

Universal ScriptCleoooCleooo 1.6K views 4.6K executesUpdated Jul 2, 2026
Unrated
00
Lua Script•1747 lines (69954 chars)
--[[ 
  Aim Assist Pro UI
]]

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local StarterGui = game:GetService("StarterGui")
local TextService = game:GetService("TextService")
local camera = workspace.CurrentCamera
local player = Players.LocalPlayer

local defaultConfig = {
    MAX_VIEW_ANGLE = 90,
    MAX_AIM_DISTANCE = 9999,
    AIM_KEY = Enum.KeyCode.R,
    HIGHLIGHT_KEY = Enum.KeyCode.T,
    MENU_KEY = Enum.KeyCode.RightControl,
    TELEPORT_KEY = Enum.KeyCode.C,
    MARK_KEY = Enum.KeyCode.G,
    HIGHLIGHT_COLOR = Color3.new(0, 1, 0),
    CAMERA_OFFSET = Vector3.new(0, 2.5, 0),
    MobileButton = {
        Size = UDim2.new(0, 80, 0, 80),
        Position = UDim2.new(0.85, 0, 0.7, 0),
        Image = "rbxassetid://5113422114",
        ButtonColor = Color3.fromRGB(25,25,25),
        ButtonTransparency = 0.25,
        DragStrokeColor = Color3.fromRGB(255,255,0),
        DragStrokeThickness = 3,
    },
    DistanciaMinimaJugador = 2.0,
    DistanciaMinimaNPC = 10.0,
    DragThreshold = 0.6,
    DisableAfterMove = 0.25,
    ENABLE_AIMING = true,
    AIM_HOLD_MODE = true,
    WALL_PENETRATION = false,

    -- Nuevas opciones de suavizado (smoothing)
    ENABLE_AIM_SMOOTHING = false,
    SMOOTHING_SPEED = 10,

    -- Nuevas opciones de teletransportación
    LOCKED_TELEPORT = false,
    TELEPORT_DISTANCE = 3,
    
    -- Cambio automático de objetivo
    AUTO_TARGET = false,
    
    -- Marcar jugadores
    ENABLE_MARKING = false,

    -- Puntero personalizado del menú
    ENABLE_CUSTOM_CURSOR = true,

    -- Estilo único para todos los botones de estado
    BUTTON_BG_COLOR = Color3.fromRGB(70,70,70),
    BUTTON_TEXT_COLOR = Color3.new(1,1,1),
    TOGGLE_LABEL_ON = "Activo",
    TOGGLE_LABEL_OFF = "Apagado",
    CUSTOM_CURSOR_COLOR = Color3.fromRGB(255,255,255),
}

local config = {}
for k,v in pairs(defaultConfig) do config[k] = v end

local targetCharacter = nil
local highlight = nil
local isTargeting = false
local isTeleportLocked = false
local markedCharacters = {}     -- tabla: {player, character, highlight, color, healthUpdateConnection}
local menuGui = nil
local menuOpen = false
local currentNotification = nil
local sliderRefs = {}
local settingsBoxes = {}
local keysBoxes = {}
local colorBtn = nil
local screenGuiMobile = nil
local aimButton = nil
local dragStroke = nil
local longPressTimer = nil
local longPressTriggered = false
local blockActivationUntil = 0
local dragLocked = false
local mobileMiraBillboard = nil
local distanciaCamaraInicial = 12
local targetInfoUpdater = nil
local aimingThread = nil
local lockedTeleportThread = nil
local gameControllingCamera = false
local prevMouseIconEnabled = UserInputService.MouseIconEnabled

local customCursorConn = nil
local customCursorGui = nil
local customCursorFrame = nil
local CUSTOM_CURSOR_SIZE = 16
local CUSTOM_CURSOR_TRANSPARENCY = 0.35
local CUSTOM_CURSOR_COLOR = Color3.fromRGB(255,255,255)
local CURSOR_DISPLAY_ORDER = 1000000

local toggleBtn = nil
local aimModeBtn = nil
local wallPenetrationBtn = nil
local smoothingBtn = nil
local lockedTeleportBtn = nil
local autoTargetBtn = nil
local markingBtn = nil

local targetDiedConnection = nil
local targetAncestryConnection = nil

local markedListUpdateRef = nil

-- Funciones auxiliares
local function cropText(text, maxChars)
    maxChars = maxChars or 18
    if #text > maxChars then
        return string.sub(text, 1, maxChars - 3) .. "..."
    end
    return text
end

local function keyLetter(keycode)
    local result = tostring(keycode):match("KeyCode%.(.+)")
    if result then
        if #result == 1 then return result:upper() end
        if result:sub(1,3) == "Num" then return result:sub(4) end
        local map = { ["Space"]="⎵", ["Return"]="⏎", ["Tab"]="Tab", ["Backspace"]="⌫", ["Delete"]="⌦", ["RightControl"]="Ctrl", ["LeftShift"]="Shift" }
        return map[result] or result:sub(1,3):upper()
    end
    return "?"
end

local function bindLabel(bind)
    if typeof(bind) == "EnumItem" then
        local s = tostring(bind)
        if s:find("KeyCode") then
            return keyLetter(bind)
        elseif s:find("UserInputType") then
            local name = s:match("UserInputType%.(.+)")
            local map = { MouseButton1 = "M1", MouseButton2 = "M2", MouseButton3 = "M3", Touch = "Touch" }
            return map[name] or name
        end
    end
    return "?"
end

local function isBindMatch(bind, input)
    if not bind or not input then return false end
    if typeof(bind) ~= "EnumItem" then return false end
    local bindStr = tostring(bind)
    if bindStr:find("KeyCode") and input.UserInputType == Enum.UserInputType.Keyboard and input.KeyCode then
        return input.KeyCode == bind
    elseif bindStr:find("UserInputType") then
        return input.UserInputType == bind
    end
    return false
end

local function showNotification(text)
    if currentNotification then
        pcall(function() currentNotification:Destroy() end)
        currentNotification = nil
    end
    local gui = Instance.new("ScreenGui")
    gui.Name = "AimAssistNotification"
    gui.IgnoreGuiInset = true
    gui.ResetOnSpawn = false
    gui.DisplayOrder = 9999
    gui.ZIndexBehavior = Enum.ZIndexBehavior.Global
    gui.Parent = player:WaitForChild("PlayerGui")
    local label = Instance.new("TextLabel")
    label.Parent = gui
    label.BackgroundColor3 = Color3.fromRGB(22,22,34)
    label.BackgroundTransparency = 0.18
    label.TextColor3 = Color3.new(1,1,1)
    label.Font = Enum.Font.GothamBold
    label.TextSize = 18
    label.Text = text
    label.TextWrapped = true
    label.TextXAlignment = Enum.TextXAlignment.Center
    label.TextYAlignment = Enum.TextYAlignment.Center
    label.AnchorPoint = Vector2.new(0.5, 0)
    label.ZIndex = 9999
    label.ClipsDescendants = true
    Instance.new("UICorner", label).CornerRadius = UDim.new(0,12)
    local maxWidth = math.clamp((camera and camera.ViewportSize.X or 800) - 80, 180, 1000)
    local textSizeVector = TextService:GetTextSize(text, label.TextSize, label.Font, Vector2.new(maxWidth, 9999))
    local paddingX = 36
    local paddingY = 18
    local finalWidth = math.clamp(textSizeVector.X + paddingX, 120, maxWidth)
    local finalHeight = textSizeVector.Y + paddingY
    label.Size = UDim2.new(0, finalWidth, 0, finalHeight)
    label.Position = UDim2.new(0.5, 0, 0.06, 0)
    currentNotification = gui
    local baseTime = 1.6
    local extraPerChar = 0.03
    local maxTime = 6
    local t = math.clamp(baseTime + #text * extraPerChar, baseTime, maxTime)
    task.delay(t, function()
        if gui == currentNotification then
            pcall(function() gui:Destroy() end)
            if currentNotification == gui then currentNotification = nil end
        end
    end)
end

local function isRagdolling()
    local character = player.Character
    if not character then return false end
    local rag = character:FindFirstChild("Ragdoll")
    if not rag then return false end
    if rag:IsA("BoolValue") then return rag.Value end
    if rag:IsA("Configuration") and rag.Enabled ~= nil then return rag.Enabled end
    return false
end

local function setMouseIconVisible(visible)
    if not UserInputService.MouseEnabled then return end
    pcall(function() UserInputService.MouseIconEnabled = visible end)
end

local function isVisible(part)
    local origin = camera.CFrame.Position
    local dir = (part.Position - origin)
    local rayParams = RaycastParams.new()
    rayParams.FilterDescendantsInstances = {player.Character}
    rayParams.FilterType = Enum.RaycastFilterType.Blacklist
    local r = workspace:Raycast(origin, dir, rayParams)
    if r and not r.Instance:IsDescendantOf(part.Parent) then return false end
    return true
end

local function isPlayerModel(model)
    return Players:GetPlayerFromCharacter(model) ~= nil
end

local function getBestTarget()
    local best = nil
    local bestScore = math.huge
    local screenCenter = Vector2.new(camera.ViewportSize.X/2, camera.ViewportSize.Y/2)
    local mousePos = Vector2.new(UserInputService:GetMouseLocation().X, UserInputService:GetMouseLocation().Y)
    
    for _, obj in ipairs(workspace:GetDescendants()) do
        if obj:IsA("Model") and obj ~= player.Character then
            local hrp = obj:FindFirstChild("HumanoidRootPart")
            local hum = obj:FindFirstChildOfClass("Humanoid")
            if hrp and hum and hum.Health > 0 then
                if not config.WALL_PENETRATION and not isVisible(hrp) then continue end
                
                local playerRoot = player.Character and player.Character:FindFirstChild("HumanoidRootPart")
                if not playerRoot then continue end
                
                local dist = (hrp.Position - playerRoot.Position).Magnitude
                local esJugador = isPlayerModel(obj)
                local minReq = esJugador and config.DistanciaMinimaJugador or config.DistanciaMinimaNPC
                if dist <= minReq then continue end
                
                local dir = (hrp.Position - camera.CFrame.Position).Unit
                local angle = math.deg(math.acos(math.clamp(dir:Dot(camera.CFrame.LookVector), -1, 1)))
                if angle > config.MAX_VIEW_ANGLE then continue end
                if dist > config.MAX_AIM_DISTANCE then continue end
                
                local pos, onScreen = camera:WorldToScreenPoint(hrp.Position)
                if not onScreen then continue end
                
                local screenVec = Vector2.new(pos.X, pos.Y)
                local useCenter = not UserInputService.MouseEnabled
                local score = (useCenter and (screenVec - screenCenter) or (screenVec - mousePos)).Magnitude
                
                if score < bestScore then bestScore = score; best = obj end
            end
        end
    end
    return best
end

local function computeDesiredCameraCFrame(char)
    if not char or not player.Character then return nil end
    local hrp = char:FindFirstChild("HumanoidRootPart")
    local playerRoot = player.Character and player.Character:FindFirstChild("HumanoidRootPart")
    if not hrp or not playerRoot then return nil end
    
    local targetPos = hrp.Position
    local originCamara = playerRoot.Position + Vector3.new(0, config.CAMERA_OFFSET.Y, 0)
    local rightVec = playerRoot.CFrame.RightVector
    originCamara = originCamara + rightVec * config.CAMERA_OFFSET.X
    
    local dirCam = (originCamara - targetPos).Unit
    local posicionIdeal = originCamara + dirCam * distanciaCamaraInicial
    
    local rayParams = RaycastParams.new()
    rayParams.FilterDescendantsInstances = {player.Character}
    rayParams.FilterType = Enum.RaycastFilterType.Blacklist
    local rayRes = workspace:Raycast(originCamara, (posicionIdeal - originCamara).Unit * distanciaCamaraInicial, rayParams)
    
    local posicionFinal = rayRes and (originCamara + dirCam * (rayRes.Distance * 0.9)) or posicionIdeal
    local desiredLook = (targetPos - posicionFinal).Unit
    
    return CFrame.new(posicionFinal, posicionFinal + desiredLook)
end

local function toggleHighlightOn(target)
    if highlight then
        highlight:Destroy()
        highlight = nil
    elseif target then
        highlight = Instance.new("Highlight")
        highlight.Parent = target
        highlight.Adornee = target
        highlight.FillColor = config.HIGHLIGHT_COLOR
        highlight.OutlineColor = config.HIGHLIGHT_COLOR
        highlight.FillTransparency = 1
        highlight.OutlineTransparency = 0
        highlight.DepthMode = Enum.HighlightDepthMode.AlwaysOnTop
    end
end

local function removeHighlight()
    if highlight then
        highlight:Destroy()
        highlight = nil
    end
end

local function updateHighlight()
    if highlight and targetCharacter and highlight.Adornee ~= targetCharacter then
        highlight:Destroy()
        highlight = nil
        highlight = Instance.new("Highlight")
        highlight.Parent = targetCharacter
        highlight.Adornee = targetCharacter
        highlight.FillColor = config.HIGHLIGHT_COLOR
        highlight.OutlineColor = config.HIGHLIGHT_COLOR
        highlight.FillTransparency = 1
        highlight.OutlineTransparency = 0
        highlight.DepthMode = Enum.HighlightDepthMode.AlwaysOnTop
    end
end

local function isCharacterMarked(character)
    for _, data in ipairs(markedCharacters) do
        if data.character == character then
            return true, data
        end
    end
    return false
end

local function isPlayerMarked(playerObj)
    for _, data in ipairs(markedCharacters) do
        if data.player == playerObj then
            return true, data
        end
    end
    return false
end

local function toggleMarkCharacter(character, customColor)
    if not character then return end
    
    local playerObj = Players:GetPlayerFromCharacter(character)
    local isMarked, markedData = isCharacterMarked(character)
    
    if isMarked then
        -- Remover marca
        if markedData.highlight then
            pcall(function() markedData.highlight:Destroy() end)
        end
        if markedData.healthUpdateConnection then
            markedData.healthUpdateConnection:Disconnect()
        end
        for i, data in ipairs(markedCharacters) do
            if data.character == character then
                table.remove(markedCharacters, i)
                showNotification("Marca removida")
                break
            end
        end
    else
        -- Agregar marca
        local markColor = customColor or Color3.new(1, 0.5, 0) -- Naranja por defecto
        local markHighlight = Instance.new("Highlight")
        markHighlight.Name = "MarkedHighlight"
        markHighlight.Parent = character
        markHighlight.Adornee = character
        markHighlight.FillColor = markColor
        markHighlight.OutlineColor = markColor
        markHighlight.FillTransparency = 1
        markHighlight.OutlineTransparency = 0
        markHighlight.DepthMode = Enum.HighlightDepthMode.AlwaysOnTop
        
        table.insert(markedCharacters, {
            player = playerObj,
            character = character,
            highlight = markHighlight,
            color = markColor,
            healthUpdateConnection = nil
        })
        showNotification("Jugador marcado")
    end
end

local function cleanMarkedCharacters()
    local toRemove = {}
    for i, data in ipairs(markedCharacters) do
        if not data.character or not data.character.Parent or not data.character:FindFirstChildOfClass("Humanoid") or data.character:FindFirstChildOfClass("Humanoid").Health <= 0 then
            -- Remover automáticamente si está muerto
            if data.highlight then
                pcall(function() data.highlight:Destroy() end)
            end
            if data.healthUpdateConnection then
                data.healthUpdateConnection:Disconnect()
            end
            
            -- MOSTRAR MENSAJE DE MUERTE
            local ply = data.player
            local displayName = ply and (ply.DisplayName or ply.Name) or (data.character and data.character.Name or "Desconocido")
            showNotification(displayName .. " murió ⚠️")
            
            table.insert(toRemove, i)
        end
    end
    
    -- Remover en orden inverso para evitar problemas de índice
    for i = #toRemove, 1, -1 do
        table.remove(markedCharacters, toRemove[i])
    end
end

local function unmarkAllCharacters()
    for _, data in ipairs(markedCharacters) do
        if data.highlight then
            pcall(function() data.highlight:Destroy() end)
        end
        if data.healthUpdateConnection then
            data.healthUpdateConnection:Disconnect()
        end
    end
    markedCharacters = {}
end

local function teleportBehindTarget()
    if not targetCharacter then return end
    local hrp = targetCharacter:FindFirstChild("HumanoidRootPart")
    local tHum = targetCharacter:FindFirstChildOfClass("Humanoid")
    if not hrp or not tHum or tHum.Health <= 0 then return end
    local playerRoot = player.Character and player.Character:FindFirstChild("HumanoidRootPart")
    if not playerRoot then return end
    
    local back = hrp.CFrame.LookVector * -config.TELEPORT_DISTANCE
    playerRoot.CFrame = CFrame.new(hrp.Position + back)
    
    if config.LOCKED_TELEPORT then
        isTeleportLocked = true
        showNotification("¡Teletransportado y bloqueado!")
    else
        showNotification("¡Teletransportado detrás de "..(targetCharacter.Name or "objetivo").."!")
    end
end

local function startLockedTeleport()
    local lockedTeleportThread = RunService.Heartbeat:Connect(function()
        pcall(function()
            if not isTeleportLocked or not targetCharacter then return end
            
            local hrp = targetCharacter:FindFirstChild("HumanoidRootPart")
            local tHum = targetCharacter:FindFirstChildOfClass("Humanoid")
            if not hrp or not tHum or tHum.Health <= 0 then
                isTeleportLocked = false
                return
            end
            
            local playerRoot = player.Character and player.Character:FindFirstChild("HumanoidRootPart")
            if not playerRoot then return end
            
            local back = hrp.CFrame.LookVector * -config.TELEPORT_DISTANCE
            playerRoot.CFrame = CFrame.new(hrp.Position + back)
        end)
    end)
end

local function stopLockedTeleport()
    isTeleportLocked = false
end

local function makeSlider(parent, labelText, min, max, getValue, setValue)
    local box = Instance.new("Frame")
    box.Size = UDim2.new(1,0,0,48)
    box.BackgroundTransparency = 1
    box.Parent = parent
    
    local label = Instance.new("TextLabel", box)
    label.Size = UDim2.new(0.56,-12,1,0)
    label.Position = UDim2.new(0,12,0,0)
    label.BackgroundTransparency = 1
    label.TextColor3 = Color3.new(1,1,1)
    label.Font = Enum.Font.Gotham
    label.Text = labelText
    label.TextSize = 16
    label.TextXAlignment = Enum.TextXAlignment.Left
    
    local bar = Instance.new("Frame", box)
    bar.Size = UDim2.new(0.42,0,0,10)
    bar.Position = UDim2.new(0.56, 8, 0.5, -5)
    bar.BackgroundColor3 = Color3.fromRGB(60,80,120)
    Instance.new("UICorner", bar).CornerRadius = UDim.new(0,6)
    
    local fill = Instance.new("Frame", bar)
    local pct = (getValue() - min) / (max - min)
    fill.Size = UDim2.new(math.clamp(pct,0,1), 0, 1, 0)
    fill.BackgroundColor3 = Color3.fromRGB(90,180,255)
    Instance.new("UICorner", fill).CornerRadius = UDim.new(0,6)
    
    local valueLabel = Instance.new("TextLabel", box)
    valueLabel.Size = UDim2.new(0,56,0,28)
    valueLabel.Position = UDim2.new(1,-68,0.5,-14)
    valueLabel.BackgroundTransparency = 1
    valueLabel.Font = Enum.Font.GothamBold
    valueLabel.TextSize = 16
    valueLabel.TextColor3 = Color3.new(1,1,1)
    valueLabel.Text = string.format("%.1f", getValue())
    
    local dragging = false
    bar.InputBegan:Connect(function(input) 
        if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then 
            dragging = true 
        end 
    end)
    bar.InputEnded:Connect(function(input) 
        if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then 
            dragging = false 
        end 
    end)
    
    UserInputService.InputChanged:Connect(function(input)
        if dragging and input.UserInputType == Enum.UserInputType.MouseMovement then
            local x = input.Position.X
            local abs = bar.AbsolutePosition.X
            local w = bar.AbsoluteSize.X
            local p = math.clamp((x - abs) / w, 0, 1)
            local newValue = math.floor((min + (max - min) * p) * 10 + 0.5) / 10
            setValue(newValue)
            fill.Size = UDim2.new(p,0,1,0)
            valueLabel.Text = string.format("%.1f", newValue)
        end
    end)
    
    table.insert(sliderRefs, function()
        local p = (getValue() - min) / (max - min)
        fill.Size = UDim2.new(math.clamp(p,0,1),0,1,0)
        valueLabel.Text = string.format("%.1f", getValue())
    end)
    
    return box
end

local function refreshMenuUI()
    if menuGui and menuGui.Parent then
        for _, obj in ipairs(sliderRefs) do
            pcall(function() obj() end)
        end
        for _, set in ipairs(settingsBoxes) do
            local inputBox = set.input
            local key = set.configkey
            inputBox.Text = (key == "MAX_AIM_DISTANCE" and config[key] == math.huge)
                and "Sin límites"
                or tostring(config[key])
        end
        if colorBtn and colorBtn.Parent then
            colorBtn.BackgroundColor3 = config.HIGHLIGHT_COLOR
        end
        for _, kset in ipairs(keysBoxes) do
            local btn = kset.button
            local key = kset.configkey
            btn.Text = bindLabel(config[key])
        end
        -- Todos los toggles usan el mismo estilo y el mismo estado textual.
        -- La única excepción intencional es Modo Apuntado: Mantener/Alternar.
        local toggleButtons = {
            {button = toggleBtn, value = config.ENABLE_AIMING},
            {button = wallPenetrationBtn, value = config.WALL_PENETRATION},
            {button = smoothingBtn, value = config.ENABLE_AIM_SMOOTHING},
            {button = lockedTeleportBtn, value = config.LOCKED_TELEPORT},
            {button = autoTargetBtn, value = config.AUTO_TARGET},
            {button = markingBtn, value = config.ENABLE_MARKING},
        }
        for _, item in ipairs(toggleButtons) do
            if item.button and item.button.Parent then
                item.button.BackgroundColor3 = config.BUTTON_BG_COLOR
                item.button.TextColor3 = config.BUTTON_TEXT_COLOR
                item.button.Text = item.value and config.TOGGLE_LABEL_ON or config.TOGGLE_LABEL_OFF
            end
        end
        if aimModeBtn and aimModeBtn.Parent then
            aimModeBtn.BackgroundColor3 = config.BUTTON_BG_COLOR
            aimModeBtn.TextColor3 = config.BUTTON_TEXT_COLOR
            aimModeBtn.Text = config.AIM_HOLD_MODE and "Mantener" or "Alternar"
        end
    end
end

local function createCustomCursor()
    if customCursorConn then customCursorConn:Disconnect() customCursorConn = nil end
    if customCursorGui then customCursorGui:Destroy(); customCursorGui = nil end

    local gui = Instance.new("ScreenGui")
    gui.Name = "AimAssistCursor"
    gui.IgnoreGuiInset = true
    gui.ResetOnSpawn = false
    gui.ZIndexBehavior = Enum.ZIndexBehavior.Global
    gui.DisplayOrder = CURSOR_DISPLAY_ORDER
    gui.Parent = player:WaitForChild("PlayerGui")

    local frame = Instance.new("Frame", gui)
    frame.Name = "CustomCursor"
    frame.Size = UDim2.new(0, CUSTOM_CURSOR_SIZE, 0, CUSTOM_CURSOR_SIZE)
    frame.AnchorPoint = Vector2.new(0.5, 0.5)
    frame.Position = UDim2.new(0, -1000, 0, -1000)
    frame.BackgroundColor3 = config.CUSTOM_CURSOR_COLOR
    frame.BackgroundTransparency = CUSTOM_CURSOR_TRANSPARENCY
    frame.ZIndex = CURSOR_DISPLAY_ORDER + 1
    Instance.new("UICorner", frame).CornerRadius = UDim.new(1,0)

    customCursorGui = gui
    customCursorFrame = frame

    customCursorConn = RunService.RenderStepped:Connect(function()
        if not customCursorFrame or not customCursorFrame.Parent then
            if customCursorConn then customCursorConn:Disconnect(); customCursorConn = nil end
            return
        end
        local m = UserInputService:GetMouseLocation()
        customCursorFrame.Position = UDim2.fromOffset(m.X, m.Y)
    end)

    setMouseIconVisible(false)
end

local function destroyCustomCursor()
    if customCursorConn then customCursorConn:Disconnect(); customCursorConn = nil end
    if customCursorGui then
        pcall(function() customCursorGui:Destroy() end)
        customCursorGui = nil
        customCursorFrame = nil
    end
    if UserInputService.MouseEnabled then
        if isTargeting and not menuOpen then
            setMouseIconVisible(false)
        else
            setMouseIconVisible(prevMouseIconEnabled)
        end
    end
end

local function createMenuGui()
    if menuGui then menuGui:Destroy() end
    sliderRefs = {}

    local gui = Instance.new("ScreenGui")
    gui.Name = "AimAssistMenu"
    gui.IgnoreGuiInset = true
    gui.ResetOnSpawn = false
    gui.DisplayOrder = 10000
    gui.ZIndexBehavior = Enum.ZIndexBehavior.Global
    gui.Parent = player:WaitForChild("PlayerGui")

    local bg = Instance.new("Frame", gui)
    bg.Size = UDim2.new(1,0,1,0)
    bg.BackgroundColor3 = Color3.fromRGB(14,14,22)
    bg.BackgroundTransparency = 0.2
    Instance.new("UICorner", bg).CornerRadius = UDim.new(0,0)
    
    local frame = Instance.new("Frame", bg)
    frame.Size = UDim2.new(0,420,0,560)
    frame.Position = UDim2.new(0.5, -210, 0.5, -280)
    frame.BackgroundColor3 = Color3.fromRGB(35,38,60)
    Instance.new("UICorner", frame).CornerRadius = UDim.new(0,18)
    
    local title = Instance.new("TextLabel", frame)
    title.Size = UDim2.new(1,0,0,48)
    title.Position = UDim2.new(0,0,0,0)
    title.BackgroundTransparency = 1
    title.TextColor3 = Color3.new(1,1,1)
    title.Font = Enum.Font.GothamBold
    title.TextSize = 20
    title.Text = "Aim Assist Pro - Configuración"

    local scroll = Instance.new("ScrollingFrame", frame)
    scroll.Size = UDim2.new(1, -24, 0, 460)
    scroll.Position = UDim2.new(0, 12, 0, 54)
    scroll.BackgroundTransparency = 1
    scroll.AutomaticCanvasSize = Enum.AutomaticSize.Y
    scroll.VerticalScrollBarInset = Enum.ScrollBarInset.Always
    scroll.CanvasSize = UDim2.new(0, 0, 0, 0)
    scroll.ScrollBarThickness = 8
    scroll.ScrollBarImageColor3 = Color3.fromRGB(110,120,150)
    Instance.new("UICorner", scroll).CornerRadius = UDim.new(0,12)

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

    local leftPad = Instance.new("Frame", scroll)
    leftPad.Size = UDim2.new(1, 0, 0, 6)
    leftPad.BackgroundTransparency = 1

    -- Toggle global para activar/desactivar apuntado
    local toggleBox = Instance.new("Frame", scroll)
    toggleBox.Size = UDim2.new(1,0,0,44)
    toggleBox.BackgroundTransparency = 1
    
    local toggleLabel = Instance.new("TextLabel", toggleBox)
    toggleLabel.Size = UDim2.new(0.6,-10,1,0)
    toggleLabel.Position = UDim2.new(0,12,0,0)
    toggleLabel.BackgroundTransparency = 1
    toggleLabel.TextColor3 = Color3.new(1,1,1)
    toggleLabel.Font = Enum.Font.Gotham
    toggleLabel.Text = "Activar Apuntado"
    toggleLabel.TextSize = 16
    toggleLabel.TextXAlignment = Enum.TextXAlignment.Left
    
    toggleBtn = Instance.new("TextButton", toggleBox)
    toggleBtn.Size = UDim2.new(0.35,-8,0,30)
    toggleBtn.Position = UDim2.new(0.65,0,0,9)
    toggleBtn.BackgroundColor3 = config.BUTTON_BG_COLOR
    toggleBtn.TextColor3 = config.BUTTON_TEXT_COLOR
    toggleBtn.Font = Enum.Font.GothamBold
    toggleBtn.TextSize = 14
    toggleBtn.Text = config.ENABLE_AIMING and config.TOGGLE_LABEL_ON or config.TOGGLE_LABEL_OFF
    Instance.new("UICorner", toggleBtn).CornerRadius = UDim.new(0,8)
    
    toggleBtn.MouseButton1Click:Connect(function()
        config.ENABLE_AIMING = not config.ENABLE_AIMING
        toggleBtn.Text = config.ENABLE_AIMING and config.TOGGLE_LABEL_ON or config.TOGGLE_LABEL_OFF
        showNotification("Apuntado: " .. (config.ENABLE_AIMING and "Activado" or "Desactivado"))
    end)

    -- Modo de apuntado: Mantener (hold) / Alternar (toggle)
    local aimModeBox = Instance.new("Frame", scroll)
    aimModeBox.Size = UDim2.new(1,0,0,44)
    aimModeBox.BackgroundTransparency = 1
    
    local aimModeLabel = Instance.new("TextLabel", aimModeBox)
    aimModeLabel.Size = UDim2.new(0.6,-10,1,0)
    aimModeLabel.Position = UDim2.new(0,12,0,0)
    aimModeLabel.BackgroundTransparency = 1
    aimModeLabel.TextColor3 = Color3.new(1,1,1)
    aimModeLabel.Font = Enum.Font.Gotham
    aimModeLabel.Text = "Modo Apuntado"
    aimModeLabel.TextSize = 16
    aimModeLabel.TextXAlignment = Enum.TextXAlignment.Left
    
    aimModeBtn = Instance.new("TextButton", aimModeBox)
    aimModeBtn.Size = UDim2.new(0.35,-8,0,30)
    aimModeBtn.Position = UDim2.new(0.65,0,0,9)
    aimModeBtn.BackgroundColor3 = config.BUTTON_BG_COLOR
    aimModeBtn.TextColor3 = config.BUTTON_TEXT_COLOR
    aimModeBtn.Font = Enum.Font.GothamBold
    aimModeBtn.TextSize = 14
    aimModeBtn.Text = config.AIM_HOLD_MODE and "Mantener" or "Alternar"
    Instance.new("UICorner", aimModeBtn).CornerRadius = UDim.new(0,8)
    
    aimModeBtn.MouseButton1Click:Connect(function()
        config.AIM_HOLD_MODE = not config.AIM_HOLD_MODE
        aimModeBtn.Text = config.AIM_HOLD_MODE and "Mantener" or "Alternar"
        showNotification("Modo Apuntado: " .. (config.AIM_HOLD_MODE and "Mantener" or "Alternar"))
    end)

    -- Toggle para Wall Penetration
    local wallPenBox = Instance.new("Frame", scroll)
    wallPenBox.Size = UDim2.new(1,0,0,44)
    wallPenBox.BackgroundTransparency = 1
    
    local wallPenLabel = Instance.new("TextLabel", wallPenBox)
    wallPenLabel.Size = UDim2.new(0.6,-10,1,0)
    wallPenLabel.Position = UDim2.new(0,12,0,0)
    wallPenLabel.BackgroundTransparency = 1
    wallPenLabel.TextColor3 = Color3.new(1,1,1)
    wallPenLabel.Font = Enum.Font.Gotham
    wallPenLabel.Text = "Apuntar a través de paredes"
    wallPenLabel.TextSize = 16
    wallPenLabel.TextXAlignment = Enum.TextXAlignment.Left
    
    wallPenetrationBtn = Instance.new("TextButton", wallPenBox)
    wallPenetrationBtn.Size = UDim2.new(0.35,-8,0,30)
    wallPenetrationBtn.Position = UDim2.new(0.65,0,0,9)
    wallPenetrationBtn.BackgroundColor3 = config.BUTTON_BG_COLOR
    wallPenetrationBtn.TextColor3 = config.BUTTON_TEXT_COLOR
    wallPenetrationBtn.Font = Enum.Font.GothamBold
    wallPenetrationBtn.TextSize = 14
    wallPenetrationBtn.Text = config.WALL_PENETRATION and config.TOGGLE_LABEL_ON or config.TOGGLE_LABEL_OFF
    Instance.new("UICorner", wallPenetrationBtn).CornerRadius = UDim.new(0,8)
    
    wallPenetrationBtn.MouseButton1Click:Connect(function()
        config.WALL_PENETRATION = not config.WALL_PENETRATION
        wallPenetrationBtn.Text = config.WALL_PENETRATION and config.TOGGLE_LABEL_ON or config.TOGGLE_LABEL_OFF
        showNotification("Apuntar a través de paredes: " .. (config.WALL_PENETRATION and "Activada" or "Desactivada"))
    end)

    -- Suavizado del apuntado
    local smoothingBox = Instance.new("Frame", scroll)
    smoothingBox.Size = UDim2.new(1,0,0,44)
    smoothingBox.BackgroundTransparency = 1
    
    local smoothingLabel = Instance.new("TextLabel", smoothingBox)
    smoothingLabel.Size = UDim2.new(0.6,-10,1,0)
    smoothingLabel.Position = UDim2.new(0,12,0,0)
    smoothingLabel.BackgroundTransparency = 1
    smoothingLabel.TextColor3 = Color3.new(1,1,1)
    smoothingLabel.Font = Enum.Font.Gotham
    smoothingLabel.Text = "Suavizado de cámara"
    smoothingLabel.TextSize = 16
    smoothingLabel.TextXAlignment = Enum.TextXAlignment.Left
    smoothingLabel.TextWrapped = false
    smoothingLabel.TextTruncate = Enum.TextTruncate.AtEnd
    
    smoothingBtn = Instance.new("TextButton", smoothingBox)
    smoothingBtn.Size = UDim2.new(0.35,-8,0,30)
    smoothingBtn.Position = UDim2.new(0.65,0,0,9)
    smoothingBtn.BackgroundColor3 = config.BUTTON_BG_COLOR
    smoothingBtn.TextColor3 = config.BUTTON_TEXT_COLOR
    smoothingBtn.Font = Enum.Font.GothamBold
    smoothingBtn.TextSize = 14
    smoothingBtn.Text = config.ENABLE_AIM_SMOOTHING and config.TOGGLE_LABEL_ON or config.TOGGLE_LABEL_OFF
    Instance.new("UICorner", smoothingBtn).CornerRadius = UDim.new(0,8)
    
    smoothingBtn.MouseButton1Click:Connect(function()
        config.ENABLE_AIM_SMOOTHING = not config.ENABLE_AIM_SMOOTHING
        smoothingBtn.Text = config.ENABLE_AIM_SMOOTHING and config.TOGGLE_LABEL_ON or config.TOGGLE_LABEL_OFF
        showNotification("Suavizado del apuntado: " .. (config.ENABLE_AIM_SMOOTHING and "Activado" or "Desactivado"))
    end)

    -- Toggle para Locked Teleport
    local lockedTeleportBox = Instance.new("Frame", scroll)
    lockedTeleportBox.Size = UDim2.new(1,0,0,44)
    lockedTeleportBox.BackgroundTransparency = 1
    
    local lockedTeleportLabel = Instance.new("TextLabel", lockedTeleportBox)
    lockedTeleportLabel.Size = UDim2.new(0.6,-10,1,0)
    lockedTeleportLabel.Position = UDim2.new(0,12,0,0)
    lockedTeleportLabel.BackgroundTransparency = 1
    lockedTeleportLabel.TextColor3 = Color3.new(1,1,1)
    lockedTeleportLabel.Font = Enum.Font.Gotham
    lockedTeleportLabel.Text = "Bloqueo de Teletransporte"
    lockedTeleportLabel.TextSize = 16
    lockedTeleportLabel.TextXAlignment = Enum.TextXAlignment.Left
    
    lockedTeleportBtn = Instance.new("TextButton", lockedTeleportBox)
    lockedTeleportBtn.Size = UDim2.new(0.35,-8,0,30)
    lockedTeleportBtn.Position = UDim2.new(0.65,0,0,9)
    lockedTeleportBtn.BackgroundColor3 = config.BUTTON_BG_COLOR
    lockedTeleportBtn.TextColor3 = config.BUTTON_TEXT_COLOR
    lockedTeleportBtn.Font = Enum.Font.GothamBold
    lockedTeleportBtn.TextSize = 14
    lockedTeleportBtn.Text = config.LOCKED_TELEPORT and config.TOGGLE_LABEL_ON or config.TOGGLE_LABEL_OFF
    Instance.new("UICorner", lockedTeleportBtn).CornerRadius = UDim.new(0,8)
    
    lockedTeleportBtn.MouseButton1Click:Connect(function()
        config.LOCKED_TELEPORT = not config.LOCKED_TELEPORT
        lockedTeleportBtn.Text = config.LOCKED_TELEPORT and config.TOGGLE_LABEL_ON or config.TOGGLE_LABEL_OFF
        showNotification("Bloqueo de Teletransporte: " .. (config.LOCKED_TELEPORT and "Activado" or "Desactivado"))
    end)

    -- Auto-Target
    local autoTargetBox = Instance.new("Frame", scroll)
    autoTargetBox.Size = UDim2.new(1,0,0,44)
    autoTargetBox.BackgroundTransparency = 1
    
    local autoTargetLabel = Instance.new("TextLabel", autoTargetBox)
    autoTargetLabel.Size = UDim2.new(0.6,-10,1,0)
    autoTargetLabel.Position = UDim2.new(0,12,0,0)
    autoTargetLabel.BackgroundTransparency = 1
    autoTargetLabel.TextColor3 = Color3.new(1,1,1)
    autoTargetLabel.Font = Enum.Font.Gotham
    autoTargetLabel.Text = "Cambio Auto Objetivo"
    autoTargetLabel.TextSize = 16
    autoTargetLabel.TextXAlignment = Enum.TextXAlignment.Left
    
    autoTargetBtn = Instance.new("TextButton", autoTargetBox)
    autoTargetBtn.Size = UDim2.new(0.35,-8,0,30)
    autoTargetBtn.Position = UDim2.new(0.65,0,0,9)
    autoTargetBtn.BackgroundColor3 = config.BUTTON_BG_COLOR
    autoTargetBtn.TextColor3 = config.BUTTON_TEXT_COLOR
    autoTargetBtn.Font = Enum.Font.GothamBold
    autoTargetBtn.TextSize = 14
    autoTargetBtn.Text = config.AUTO_TARGET and config.TOGGLE_LABEL_ON or config.TOGGLE_LABEL_OFF
    Instance.new("UICorner", autoTargetBtn).CornerRadius = UDim.new(0,8)
    
    autoTargetBtn.MouseButton1Click:Connect(function()
        config.AUTO_TARGET = not config.AUTO_TARGET
        autoTargetBtn.Text = config.AUTO_TARGET and config.TOGGLE_LABEL_ON or config.TOGGLE_LABEL_OFF
        showNotification("Cambio Auto Objetivo: " .. (config.AUTO_TARGET and "Activado" or "Desactivado"))
    end)

    -- Marcar jugadores
    local markingBox = Instance.new("Frame", scroll)
    markingBox.Size = UDim2.new(1,0,0,44)
    markingBox.BackgroundTransparency = 1
    
    local markingLabel = Instance.new("TextLabel", markingBox)
    markingLabel.Size = UDim2.new(0.6,-10,1,0)
    markingLabel.Position = UDim2.new(0,12,0,0)
    markingLabel.BackgroundTransparency = 1
    markingLabel.TextColor3 = Color3.new(1,1,1)
    markingLabel.Font = Enum.Font.Gotham
    markingLabel.Text = "Marcar jugadores"
    markingLabel.TextSize = 16
    markingLabel.TextXAlignment = Enum.TextXAlignment.Left
    
    markingBtn = Instance.new("TextButton", markingBox)
    markingBtn.Size = UDim2.new(0.35,-8,0,30)
    markingBtn.Position = UDim2.new(0.65,0,0,9)
    markingBtn.BackgroundColor3 = config.BUTTON_BG_COLOR
    markingBtn.TextColor3 = config.BUTTON_TEXT_COLOR
    markingBtn.Font = Enum.Font.GothamBold
    markingBtn.TextSize = 14
    markingBtn.Text = config.ENABLE_MARKING and config.TOGGLE_LABEL_ON or config.TOGGLE_LABEL_OFF
    Instance.new("UICorner", markingBtn).CornerRadius = UDim.new(0,8)
    
    markingBtn.MouseButton1Click:Connect(function()
        config.ENABLE_MARKING = not config.ENABLE_MARKING
        markingBtn.Text = config.ENABLE_MARKING and config.TOGGLE_LABEL_ON or config.TOGGLE_LABEL_OFF
        if not config.ENABLE_MARKING then
            unmarkAllCharacters()
        end
        showNotification("Marcar jugadores: " .. (config.ENABLE_MARKING and "ON" or "OFF"))
    end)

    -- Puntero personalizado, con el mismo formato visual de los demás interruptores.
    local cursorRow = Instance.new("Frame", scroll)
    cursorRow.Size = UDim2.new(1, 0, 0, 48)
    cursorRow.BackgroundTransparency = 1

    local cursorLabel = Instance.new("TextLabel", cursorRow)
    cursorLabel.Size = UDim2.new(0.6, -10, 1, 0)
    cursorLabel.Position = UDim2.new(0, 12, 0, 0)
    cursorLabel.BackgroundTransparency = 1
    cursorLabel.TextColor3 = Color3.new(1,1,1)
    cursorLabel.Font = Enum.Font.Gotham
    cursorLabel.Text = "Puntero personalizado"
    cursorLabel.TextSize = 16
    cursorLabel.TextXAlignment = Enum.TextXAlignment.Left

    local cursorBtn = Instance.new("TextButton", cursorRow)
    cursorBtn.Size = UDim2.new(0.35, -8, 0, 30)
    cursorBtn.Position = UDim2.new(0.65, 0, 0, 9)
    cursorBtn.BackgroundColor3 = config.BUTTON_BG_COLOR
    cursorBtn.TextColor3 = Color3.new(1,1,1)
    cursorBtn.Font = Enum.Font.GothamBold
    cursorBtn.TextSize = 16
    cursorBtn.Text = config.ENABLE_CUSTOM_CURSOR and config.TOGGLE_LABEL_ON or config.TOGGLE_LABEL_OFF
    Instance.new("UICorner", cursorBtn).CornerRadius = UDim.new(0,8)

    cursorBtn.MouseButton1Click:Connect(function()
        config.ENABLE_CUSTOM_CURSOR = not config.ENABLE_CUSTOM_CURSOR
        cursorBtn.Text = config.ENABLE_CUSTOM_CURSOR and config.TOGGLE_LABEL_ON or config.TOGGLE_LABEL_OFF

        if config.ENABLE_CUSTOM_CURSOR then
            createCustomCursor()
        else
            destroyCustomCursor()
        end

        showNotification("Puntero personalizado: " .. (config.ENABLE_CUSTOM_CURSOR and "Activo" or "Apagado"))
    end)

    settingsBoxes = {}
    -- Configuración numérica, ordenada por función.
    local settings = {
        {"Ángulo máximo de apuntado", "MAX_VIEW_ANGLE", 0, 180, 1},
        {"Distancia máxima de apuntado", "MAX_AIM_DISTANCE", 1, 10000, 1},
        {"Distancia de teletransporte", "TELEPORT_DISTANCE", -500, 1000, 1},
    }
    
    for _, set in ipairs(settings) do
        local box = Instance.new("Frame", scroll)
        box.Size = UDim2.new(1,0,0,48)
        box.BackgroundTransparency = 1
        
        local label = Instance.new("TextLabel", box)
        label.Size = UDim2.new(0.6,-10,1,0)
        label.Position = UDim2.new(0,12,0,0)
        label.BackgroundTransparency = 1
        label.TextColor3 = Color3.new(1,1,1)
        label.Font = Enum.Font.Gotham
        label.Text = set[1]
        label.TextSize = 16
        label.TextXAlignment = Enum.TextXAlignment.Left

        local inputBox = Instance.new("TextBox", box)
        inputBox.Size = UDim2.new(0.35,-8,0,30)
        inputBox.Position = UDim2.new(0.65,0,0,9)
        inputBox.BackgroundColor3 = Color3.fromRGB(45,65,100)
        inputBox.TextColor3 = Color3.new(1,1,1)
        inputBox.Font = Enum.Font.GothamBold
        inputBox.TextSize = 16
        inputBox.ClearTextOnFocus = false
        inputBox.Text = tostring(config[set[2]])
        Instance.new("UICorner", inputBox).CornerRadius = UDim.new(0,8)
        
        -- Solo permitir números en la distancia máxima.
        if set[2] == "MAX_AIM_DISTANCE" then
            inputBox:GetPropertyChangedSignal("Text"):Connect(function()
                if inputBox.Text == "Sin límites" then
                    return
                end

                local filtered = inputBox.Text:gsub("%D", "")
                if filtered ~= inputBox.Text then
                    inputBox.Text = filtered
                end
            end)

            inputBox.Focused:Connect(function()
                if config[set[2]] == math.huge or inputBox.Text == "Sin límites" then
                    inputBox.Text = ""
                end
            end)
        end

        inputBox.FocusLost:Connect(function()
            local newVal = tonumber(inputBox.Text)

            if newVal then
                -- 10000 o más = distancia de apuntado sin límites.
                if set[2] == "MAX_AIM_DISTANCE" and newVal >= 10000 then
                    config[set[2]] = math.huge
                    inputBox.Text = "Sin límites"
                else
                    newVal = math.clamp(newVal, set[3], set[4])
                    config[set[2]] = newVal
                    inputBox.Text = tostring(newVal)
                end
            elseif set[2] == "MAX_AIM_DISTANCE" and inputBox.Text == "" then
                config[set[2]] = math.huge
                inputBox.Text = "Sin límites"
            else
                inputBox.Text = config[set[2]] == math.huge and "Sin límites" or tostring(config[set[2]])
            end

            refreshMenuUI()
        end)
        
        table.insert(settingsBoxes, {input=inputBox, configkey=set[2]})
    end

    makeSlider(scroll, "Desplazamiento X", -5, 5,
        function() return tonumber(string.format("%.1f", config.CAMERA_OFFSET.X)) end,
        function(x) config.CAMERA_OFFSET = Vector3.new(x, config.CAMERA_OFFSET.Y, 0) end
    )
    
    makeSlider(scroll, "Desplazamiento Y", -5, 5,
        function() return tonumber(string.format("%.1f", config.CAMERA_OFFSET.Y)) end,
        function(y) config.CAMERA_OFFSET = Vector3.new(config.CAMERA_OFFSET.X, y, 0) end
    )

    local colorBox = Instance.new("Frame", scroll)
    colorBox.Size = UDim2.new(1,0,0,44)
    colorBox.BackgroundTransparency = 1
    
    local colorLabel = Instance.new("TextLabel", colorBox)
    colorLabel.Size = UDim2.new(0.6,-10,1,0)
    colorLabel.Position = UDim2.new(0,12,0,0)
    colorLabel.BackgroundTransparency = 1
    colorLabel.Text = "Color del Contorno"
    colorLabel.Font = Enum.Font.Gotham
    colorLabel.TextSize = 16
    colorLabel.TextColor3 = Color3.new(1,1,1)
    colorLabel.TextXAlignment = Enum.TextXAlignment.Left
    
    colorBtn = Instance.new("TextButton", colorBox)
    colorBtn.Size = UDim2.new(0.35,-8,0,30)
    colorBtn.Position = UDim2.new(0.65,0,0,9)
    colorBtn.BackgroundColor3 = config.HIGHLIGHT_COLOR
    colorBtn.Text = ""
    Instance.new("UICorner", colorBtn).CornerRadius = UDim.new(0,8)
    
    colorBtn.MouseButton1Click:Connect(function()
        local colors = {Color3.new(0,1,0), Color3.new(1,0,0), Color3.new(0,0,1), Color3.new(1,1,0), Color3.new(1,0,1), Color3.new(0,1,1), Color3.new(1,1,1)}
        local idx = table.find(colors, config.HIGHLIGHT_COLOR) or 0
        idx = idx + 1
        if idx > #colors then idx = 1 end
        config.HIGHLIGHT_COLOR = colors[idx]
        colorBtn.BackgroundColor3 = config.HIGHLIGHT_COLOR
        if highlight then highlight.FillColor = config.HIGHLIGHT_COLOR; highlight.OutlineColor = config.HIGHLIGHT_COLOR end
        refreshMenuUI()
    end)

    local keySettings = {
        {"Tecla apuntar", "AIM_KEY"},
        {"Tecla resaltar", "HIGHLIGHT_KEY"},
        {"Tecla menú", "MENU_KEY"},
        {"Tecla Teleport", "TELEPORT_KEY"},
        {"Tecla Marcar", "MARK_KEY"},
    }
    
    keysBoxes = {}
    for _, set in ipairs(keySettings) do
        local keyBox = Instance.new("Frame", scroll)
        keyBox.Size = UDim2.new(1,0,0,44)
        keyBox.BackgroundTransparency = 1
        
        local keyLabel = Instance.new("TextLabel", keyBox)
        keyLabel.Size = UDim2.new(0.6,-10,1,0)
        keyLabel.Position = UDim2.new(0,12,0,0)
        keyLabel.BackgroundTransparency = 1
        keyLabel.Text = set[1]
        keyLabel.Font = Enum.Font.Gotham
        keyLabel.TextSize = 16
        keyLabel.TextColor3 = Color3.new(1,1,1)
        keyLabel.TextXAlignment = Enum.TextXAlignment.Left
        
        local keyBtn = Instance.new("TextButton", keyBox)
        keyBtn.Size = UDim2.new(0.35,-8,0,30)
        keyBtn.Position = UDim2.new(0.65,0,0,9)
        keyBtn.BackgroundColor3 = Color3.fromRGB(45,65,100)
        keyBtn.TextColor3 = Color3.new(1,1,1)
        keyBtn.Font = Enum.Font.GothamBold
        keyBtn.TextSize = 16
        keyBtn.Text = bindLabel(config[set[2]])
        Instance.new("UICorner", keyBtn).CornerRadius = UDim.new(0,8)
        
        keyBtn.MouseButton1Click:Connect(function()
            keyBtn.Text = "..."
            local conn
            conn = UserInputService.InputBegan:Connect(function(input)
                if input.UserInputType == Enum.UserInputType.Keyboard then
                    config[set[2]] = input.KeyCode
                    keyBtn.Text = bindLabel(config[set[2]])
                    showNotification("Tecla '"..set[1].."' asignada a ["..bindLabel(config[set[2]]).."]")
                    conn:Disconnect()
                    refreshMenuUI()
                elseif input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.MouseButton2 or input.UserInputType == Enum.UserInputType.MouseButton3 then
                    config[set[2]] = input.UserInputType
                    keyBtn.Text = bindLabel(config[set[2]])
                    showNotification("Tecla '"..set[1].."' asignada a ["..bindLabel(config[set[2]]).."]")
                    conn:Disconnect()
                    refreshMenuUI()
                end
            end)
        end)
        
        table.insert(keysBoxes, {button=keyBtn, configkey=set[2]})
    end

    -- Lista de jugadores marcados (MEJORADA - CON BARRAS REDONDEADAS Y VIDA DINÁMICA)
    local markedContainer = Instance.new("Frame", scroll)
    markedContainer.Size = UDim2.new(1, -24, 0, 0)
    markedContainer.BackgroundTransparency = 0
    markedContainer.BackgroundColor3 = Color3.fromRGB(28,30,44)
    markedContainer.ClipsDescendants = true
    Instance.new("UICorner", markedContainer).CornerRadius = UDim.new(0,10)

    local markedTitle = Instance.new("TextLabel", markedContainer)
    markedTitle.Size = UDim2.new(1, -16, 0, 22)
    markedTitle.Position = UDim2.new(0, 8, 0, 6)
    markedTitle.BackgroundTransparency = 1
    markedTitle.Font = Enum.Font.GothamBold
    markedTitle.Text = "Jugadores marcados"
    markedTitle.TextColor3 = Color3.new(1,1,1)
    markedTitle.TextSize = 14
    markedTitle.TextXAlignment = Enum.TextXAlignment.Center

    local markedScroll = Instance.new("ScrollingFrame", markedContainer)
    markedScroll.Size = UDim2.new(1, -16, 1, -32)
    markedScroll.Position = UDim2.new(0, 8, 0, 28)
    markedScroll.BackgroundTransparency = 1
    markedScroll.CanvasSize = UDim2.new(0, 0, 0, 0)
    markedScroll.AutomaticCanvasSize = Enum.AutomaticSize.Y
    markedScroll.ScrollBarThickness = 6
    markedScroll.ScrollBarImageColor3 = Color3.fromRGB(110,120,150)

    local markedLayout = Instance.new("UIListLayout", markedScroll)
    markedLayout.Padding = UDim.new(0, 8)
    markedLayout.SortOrder = Enum.SortOrder.LayoutOrder

    local function updateMarkedList()
        cleanMarkedCharacters()
        
        -- Limpiar lista
        for _, child in ipairs(markedScroll:GetChildren()) do
            if child ~= markedLayout then
                child:Destroy()
            end
        end

        if #markedCharacters == 0 then
            markedContainer.Size = UDim2.new(1, -24, 0, 0)
            return
        end

        -- Agregar items
        for idx, data in ipairs(markedCharacters) do
            if data.character and data.character.Parent then
                local row = Instance.new("Frame", markedScroll)
                row.Size = UDim2.new(1, 0, 0, 48)
                row.BackgroundTransparency = 1

                local ply = data.player
                local displayName = ply and (ply.DisplayName or ply.Name) or (data.character.Name or "Desconocido")
                local humanoid = data.character:FindFirstChildOfClass("Humanoid")
                local maxHealth = humanoid and humanoid.MaxHealth or 100
                local currentHealth = humanoid and humanoid.Health or 0

                -- Nombre del jugador (alineado a la izquierda)
                local nameLabel = Instance.new("TextLabel", row)
                nameLabel.Size = UDim2.new(0.3, -4, 0, 20)
                nameLabel.Position = UDim2.new(0, 0, 0, 0)
                nameLabel.BackgroundTransparency = 1
                nameLabel.Font = Enum.Font.GothamBold
                nameLabel.Text = cropText(displayName, 15)
                nameLabel.TextColor3 = data.color or Color3.new(1, 0.5, 0)
                nameLabel.TextSize = 13
                nameLabel.TextXAlignment = Enum.TextXAlignment.Left
                nameLabel.TextWrapped = false

                -- Contenedor de barra de vida (MÁS REDONDEADA)
                local healthBarBg = Instance.new("Frame", row)
                healthBarBg.Size = UDim2.new(0.7, 0, 0, 18)
                healthBarBg.Position = UDim2.new(0.3, 0, 0, 0)
                healthBarBg.BackgroundColor3 = Color3.fromRGB(30, 30, 30)
                Instance.new("UICorner", healthBarBg).CornerRadius = UDim.new(0, 9)

                -- Barra de vida (fill - MÁS REDONDEADA)
                local healthBarFill = Instance.new("Frame", healthBarBg)
                local healthPercent = math.clamp(currentHealth / maxHealth, 0, 1)
                healthBarFill.Size = UDim2.new(healthPercent, 0, 1, 0)
                healthBarFill.BackgroundColor3 = Color3.fromRGB(50, 200, 50)
                healthBarFill.BorderSizePixel = 0
                Instance.new("UICorner", healthBarFill).CornerRadius = UDim.new(0, 9)

                -- Texto de vida (DINÁMICO - ej: 700/1000)
                local healthText = Instance.new("TextLabel", healthBarBg)
                healthText.Size = UDim2.new(1, 0, 1, 0)
                healthText.BackgroundTransparency = 1
                healthText.Font = Enum.Font.GothamBold
                healthText.Text = string.format("%.0f/%.0f", currentHealth, maxHealth)
                healthText.TextColor3 = Color3.new(1, 1, 1)
                healthText.TextSize = 11
                healthText.TextXAlignment = Enum.TextXAlignment.Center
                healthText.TextYAlignment = Enum.TextYAlignment.Center
                healthText.ZIndex = 2

                -- Actualizar barra de vida continuamente
                local healthUpdateConnection
                healthUpdateConnection = RunService.Heartbeat:Connect(function()
                    if not data.character or not data.character.Parent or not humanoid or humanoid.Health <= 0 then
                        if healthUpdateConnection then
                            healthUpdateConnection:Disconnect()
                        end
                        return
                    end

                    local newHealth = humanoid.Health
                    local newMax = humanoid.MaxHealth
                    local newPercent = math.clamp(newHealth / newMax, 0, 1)

                    -- Cambiar color según la salud
                    if newPercent > 0.5 then
                        healthBarFill.BackgroundColor3 = Color3.fromRGB(50, 200, 50) -- Verde
                    elseif newPercent > 0.25 then
                        healthBarFill.BackgroundColor3 = Color3.fromRGB(255, 200, 0) -- Amarillo
                    else
                        healthBarFill.BackgroundColor3 = Color3.fromRGB(255, 80, 80) -- Rojo
                    end

                    healthBarFill.Size = UDim2.new(newPercent, 0, 1, 0)
                    healthText.Text = string.format("%.0f/%.0f", newHealth, newMax)
                end)

                -- Desconectar cuando se destruya
                row.Destroying:Connect(function()
                    if healthUpdateConnection then
                        healthUpdateConnection:Disconnect()
                    end
                end)
            end
        end

        markedContainer.Size = UDim2.new(1, -24, 0, math.min(#markedCharacters * 56 + 40, 400))
    end

    -- Actualizar lista cuando se abre el menú
    if markedListUpdateRef then markedListUpdateRef:Disconnect() end
    markedListUpdateRef = RunService.Heartbeat:Connect(function()
        if menuOpen and markedContainer.Parent then
            updateMarkedList()
        end
    end)

    local padBot = Instance.new("Frame", scroll)
    padBot.Size = UDim2.new(1, 0, 0, 22)
    padBot.BackgroundTransparency = 1
    
    local bottomStrip = Instance.new("Frame", frame)
    bottomStrip.Size = UDim2.new(1, -24, 0, 48)
    bottomStrip.Position = UDim2.new(0, 12, 1, -58)
    bottomStrip.BackgroundTransparency = 1
    
    local resetBtn = Instance.new("TextButton", bottomStrip)
    resetBtn.Size = UDim2.new(0.48, -8, 1, -12)
    resetBtn.Position = UDim2.new(0, 0, 0, 6)
    resetBtn.BackgroundColor3 = Color3.fromRGB(40,120,40)
    resetBtn.TextColor3 = Color3.new(1,1,1)
    resetBtn.Font = Enum.Font.GothamBold
    resetBtn.TextSize = 16
    resetBtn.Text = "Reiniciar"
    Instance.new("UICorner", resetBtn).CornerRadius = UDim.new(0,10)
    
    resetBtn.MouseButton1Click:Connect(function()
        for k,v in pairs(defaultConfig) do config[k] = typeof(v) == "Vector3" and v + Vector3.zero or v end

        if config.ENABLE_CUSTOM_CURSOR then
            createCustomCursor()
        else
            destroyCustomCursor()
        end

        refreshMenuUI()
        showNotification("¡Configuraciones reiniciadas!")
    end)
    
    local closeBtn = Instance.new("TextButton", bottomStrip)
    closeBtn.Size = UDim2.new(0.48, -8, 1, -12)
    closeBtn.Position = UDim2.new(0.52, 0, 0, 6)
    closeBtn.BackgroundColor3 = Color3.fromRGB(120,30,30)
    closeBtn.TextColor3 = Color3.new(1,1,1)
    closeBtn.Font = Enum.Font.GothamBold
    closeBtn.TextSize = 16
    closeBtn.Text = "Cerrar"
    Instance.new("UICorner", closeBtn).CornerRadius = UDim.new(0,10)
    
    closeBtn.MouseButton1Click:Connect(function()
        destroyCustomCursor()
        if menuGui then menuGui:Destroy(); menuGui = nil end
        menuOpen = false
        if targetInfoUpdater then targetInfoUpdater:Disconnect(); targetInfoUpdater = nil end
        if markedListUpdateRef then markedListUpdateRef:Disconnect(); markedListUpdateRef = nil end
        if isTargeting then setMouseIconVisible(false) else setMouseIconVisible(prevMouseIconEnabled) end
    end)

    if config.ENABLE_CUSTOM_CURSOR then
        createCustomCursor()
    end
    menuGui = gui
    refreshMenuUI()
end

local function cleanTargetConnections()
    if targetDiedConnection then targetDiedConnection:Disconnect(); targetDiedConnection = nil end
    if targetAncestryConnection then targetAncestryConnection:Disconnect(); targetAncestryConnection = nil end
end

local function createMobileGuiIfNeeded()
    if UserInputService.MouseEnabled then
        screenGuiMobile = nil
        aimButton = nil
        return
    end
    if screenGuiMobile then screenGuiMobile:Destroy() end
    
    local screenGui = Instance.new("ScreenGui")
    screenGui.Name = "SistemaApuntadoMovil"
    screenGui.ResetOnSpawn = false
    screenGui.Parent = player:WaitForChild("PlayerGui")
    
    local btn = Instance.new("ImageButton", screenGui)
    btn.Name = "BotonApuntar"
    btn.Size = config.MobileButton.Size
    btn.Position = config.MobileButton.Position
    btn.BackgroundColor3 = config.MobileButton.ButtonColor
    btn.BackgroundTransparency = config.MobileButton.ButtonTransparency
    btn.Image = config.MobileButton.Image
    btn.ImageColor3 = Color3.new(1,1,1)
    btn.ScaleType = Enum.ScaleType.Fit
    btn.ZIndex = 2
    Instance.new("UICorner", btn).CornerRadius = UDim.new(1,0)
    
    dragStroke = Instance.new("UIStroke", btn)
    dragStroke.Color = config.MobileButton.DragStrokeColor
    dragStroke.Thickness = config.MobileButton.DragStrokeThickness
    dragStroke.Transparency = 1.0
    
    screenGuiMobile = screenGui
    aimButton = btn
end

local function destroyMobileMira()
    if mobileMiraBillboard then 
        pcall(function() mobileMiraBillboard:Destroy() end)
        mobileMiraBillboard = nil 
    end
end

local function createMobileMiraFor(character)
    destroyMobileMira()
    local torso = character:FindFirstChild("UpperTorso") or character:FindFirstChild("Torso")
    if not torso then return end
    
    mobileMiraBillboard = Instance.new("BillboardGui")
    mobileMiraBillboard.Name = "MiraFlotante"
    mobileMiraBillboard.Adornee = torso
    mobileMiraBillboard.Size = UDim2.new(0,64,0,64)
    mobileMiraBillboard.StudsOffset = Vector3.new(0,0.6,0)
    mobileMiraBillboard.AlwaysOnTop = true
    mobileMiraBillboard.Parent = torso
    
    local point = Instance.new("Frame", mobileMiraBillboard)
    point.Name = "MiraPunto"
    point.Size = UDim2.new(0, CUSTOM_CURSOR_SIZE, 0, CUSTOM_CURSOR_SIZE)
    point.AnchorPoint = Vector2.new(0.5,0.5)
    point.Position = UDim2.new(0.5,0,0.5,0)
    point.BackgroundColor3 = config.CUSTOM_CURSOR_COLOR
    point.BackgroundTransparency = CUSTOM_CURSOR_TRANSPARENCY
    Instance.new("UICorner", point).CornerRadius = UDim.new(1,0)
end

local autoTargetThread = nil

local function activateAiming()
    if not config.ENABLE_AIMING then
        showNotification("El sistema de apuntado está desactivado en la configuración.")
        return
    end

    if isRagdolling() then
        showNotification("No se puede apuntar durante la animación.")
        return
    end
    
    if tick() < blockActivationUntil then return end
    if gameControllingCamera then showNotification("No se puede apuntar mientras el juego controla la cámara."); return end
    if not player.Character then return end
    
    local found = getBestTarget()
    if not found then 
        StarterGui:SetCore("SendNotification", {Title="Sistema de Apuntado", Text="No hay un objetivo válido.", Duration=1.6})
        return 
    end
    
    targetCharacter = found
    isTargeting = true
    isTeleportLocked = false
    
    if UserInputService.MouseEnabled then
        prevMouseIconEnabled = UserInputService.MouseIconEnabled
        if not menuOpen then setMouseIconVisible(false) end
    end
    
    local playerRoot = player.Character and player.Character:FindFirstChild("HumanoidRootPart")
    if playerRoot then 
        distanciaCamaraInicial = math.clamp((playerRoot.Position - camera.CFrame.Position).Magnitude, 6, 25) 
    else 
        distanciaCamaraInicial = 12 
    end
    
    camera.CameraType = Enum.CameraType.Scriptable
    createMobileMiraFor(targetCharacter)
    
    local msg
    do
        local ply = Players:GetPlayerFromCharacter(targetCharacter)
        if ply then 
            msg = "Apuntando a: " .. (ply.DisplayName or ply.Name)
        else 
            msg = "Apuntando a: " .. (targetCharacter.Name or "objetivo")
        end
    end
    showNotification(msg)
    
    if aimingThread then aimingThread:Disconnect() end
    
    aimingThread = RunService.RenderStepped:Connect(function(dt)
        pcall(function()
            if not isTargeting or not targetCharacter then return end
            if UserInputService.MouseEnabled and not menuOpen then
                pcall(function() UserInputService.MouseIconEnabled = false end)
            end

            local desiredCFrame = computeDesiredCameraCFrame(targetCharacter)
            if not desiredCFrame then return end

            if config.ENABLE_AIM_SMOOTHING then
                local alpha = math.clamp(config.SMOOTHING_SPEED * dt, 0, 1)
                camera.CFrame = camera.CFrame:Lerp(desiredCFrame, alpha)
            else
                camera.CFrame = desiredCFrame
            end
        end)
    end)
    
    if autoTargetThread then autoTargetThread:Disconnect(); autoTargetThread = nil end
    
    if config.AUTO_TARGET then
        autoTargetThread = RunService.Heartbeat:Connect(function()
            pcall(function()
                if not isTargeting or not config.AUTO_TARGET then return end
                
                local currentTarget = targetCharacter
                if currentTarget then
                    local hum = currentTarget:FindFirstChildOfClass("Humanoid")
                    if hum and hum.Health > 0 and currentTarget.Parent then
                        return
                    end
                end
                
                local newTarget = getBestTarget()
                if newTarget and newTarget ~= currentTarget then
                    targetCharacter = newTarget
                    updateHighlight()
                    createMobileMiraFor(newTarget)
                    local ply = Players:GetPlayerFromCharacter(newTarget)
                    local msg2 = "Objetivo cambiado a: " .. (ply and (ply.DisplayName or ply.Name) or (newTarget.Name or "objetivo"))
                    showNotification(msg2)
                end
            end)
        end)
    end
    
    cleanTargetConnections()
    
    local hum = targetCharacter:FindFirstChildOfClass("Humanoid")
    local thisTarget = targetCharacter
    
    if hum then
        targetDiedConnection = hum.Died:Connect(function()
            task.wait(0.1)
            if targetCharacter == thisTarget then
                if config.AUTO_TARGET and isTargeting then
                    local newTarget = getBestTarget()
                    if newTarget then
                        targetCharacter = newTarget
                        updateHighlight()
                        createMobileMiraFor(newTarget)
                        local ply = Players:GetPlayerFromCharacter(newTarget)
                        local msg2 = "Objetivo cambiado a: " .. (ply and (ply.DisplayName or ply.Name) or (newTarget.Name or "objetivo"))
                        showNotification(msg2)
                        return
                    end
                end
                
                isTargeting = false
                isTeleportLocked = false
                destroyMobileMira()
                removeHighlight()
                if aimingThread then aimingThread:Disconnect(); aimingThread = nil end
                if autoTargetThread then autoTargetThread:Disconnect(); autoTargetThread = nil end
                camera.CameraType = Enum.CameraType.Custom
                targetCharacter = nil
                setMouseIconVisible(prevMouseIconEnabled)
            end
        end)
    end
    
    targetAncestryConnection = thisTarget.AncestryChanged:Connect(function(child, parent)
        if not parent or not child:IsDescendantOf(workspace) then
            if config.AUTO_TARGET and isTargeting then
                local newTarget = getBestTarget()
                if newTarget then
                    targetCharacter = newTarget
                    updateHighlight()
                    createMobileMiraFor(newTarget)
                    local ply = Players:GetPlayerFromCharacter(newTarget)
                    local msg2 = "Objetivo cambiado a: " .. (ply and (ply.DisplayName or ply.Name) or (newTarget.Name or "objetivo"))
                    showNotification(msg2)
                    return
                end
            end
            
            isTargeting = false
            isTeleportLocked = false
            targetCharacter = nil
            destroyMobileMira()
            removeHighlight()
            if aimingThread then aimingThread:Disconnect(); aimingThread = nil end
            if autoTargetThread then autoTargetThread:Disconnect(); autoTargetThread = nil end
            camera.CameraType = Enum.CameraType.Custom
            cleanTargetConnections()
            setMouseIconVisible(prevMouseIconEnabled)
        end
    end)
end

local function deactivateAiming()
    isTargeting = false
    isTeleportLocked = false
    camera.CameraType = Enum.CameraType.Custom
    targetCharacter = nil
    destroyMobileMira()
    removeHighlight()
    if aimingThread then aimingThread:Disconnect(); aimingThread = nil end
    if autoTargetThread then autoTargetThread:Disconnect(); autoTargetThread = nil end
    cleanTargetConnections()
    setMouseIconVisible(prevMouseIconEnabled)
end

local function wireMobileButton()
    if not aimButton then return end
    
    aimButton.InputBegan:Connect(function(input)
        if tick() < blockActivationUntil then return end
        if input.UserInputType == Enum.UserInputType.Touch or input.UserInputType == Enum.UserInputType.MouseButton1 then
            local startTime = tick()
            longPressTriggered = false
            if longPressTimer then longPressTimer:Disconnect(); longPressTimer = nil end
            
            longPressTimer = RunService.Heartbeat:Connect(function()
                if tick() - startTime > config.DragThreshold then
                    longPressTriggered = true
                    dragLocked = not dragLocked
                    dragStroke.Transparency = dragLocked and 0.0 or 1.0
                    if longPressTimer then longPressTimer:Disconnect(); longPressTimer = nil end
                end
            end)
        end
    end)
    
    aimButton.InputEnded:Connect(function(input)
        if tick() < blockActivationUntil then
            if longPressTimer then longPressTimer:Disconnect(); longPressTimer = nil end
            return
        end
        
        if input.UserInputType == Enum.UserInputType.Touch or input.UserInputType == Enum.UserInputType.MouseButton1 then
            if longPressTimer then longPressTimer:Disconnect(); longPressTimer = nil end
            if not longPressTriggered then
                if isTargeting then deactivateAiming() else activateAiming() end
            end
            longPressTriggered = false
            if not dragLocked then dragStroke.Transparency = 1.0 end
        end
    end)
end

-- Input handlers
UserInputService.InputBegan:Connect(function(input, processed)
    if processed then return end

    if isBindMatch(config.AIM_KEY, input) then
        if config.AIM_HOLD_MODE then
            if not isTargeting then activateAiming() end
        else
            if not isTargeting then
                activateAiming()
            else
                deactivateAiming()
                showNotification("Apuntado cancelado")
            end
        end
        return
    end

    if isBindMatch(config.HIGHLIGHT_KEY, input) then
        if targetCharacter then toggleHighlightOn(targetCharacter) end
        return
    end

    if isBindMatch(config.MENU_KEY, input) then
        if not menuOpen then
            createMenuGui()
            menuOpen = true
        else
            destroyCustomCursor()
            if menuGui then menuGui:Destroy(); menuGui = nil end
            menuOpen = false
            if isTargeting then setMouseIconVisible(false) else setMouseIconVisible(prevMouseIconEnabled) end
        end
        return
    end

    if isBindMatch(config.TELEPORT_KEY, input) then
        if targetCharacter then 
            if isTeleportLocked then
                stopLockedTeleport()
                showNotification("Bloqueo de teletransporte desactivado")
            else
                teleportBehindTarget()
                if config.LOCKED_TELEPORT then
                    startLockedTeleport()
                end
            end
        end
        return
    end

    if isBindMatch(config.MARK_KEY, input) then
        if config.ENABLE_MARKING then
            cleanMarkedCharacters()
            local bestTarget = getBestTarget()
            if bestTarget then
                toggleMarkCharacter(bestTarget)
            else
                showNotification("No hay un objetivo para marcar")
            end
        end
        return
    end

    if (input.UserInputType == Enum.UserInputType.Touch or input.UserInputType == Enum.UserInputType.MouseButton1) and dragLocked and aimButton then
        local pos = input.Position
        if pos and aimButton.AbsolutePosition and aimButton.AbsoluteSize then
            local absPos = aimButton.AbsolutePosition
            local absSize = aimButton.AbsoluteSize
            if not (pos.X >= absPos.X and pos.X <= absPos.X + absSize.X and pos.Y >= absPos.Y and pos.Y <= absPos.Y + absSize.Y) then
                aimButton.Position = UDim2.fromOffset(pos.X - absSize.X/2, pos.Y - absSize.Y/2)
                dragLocked = false
                dragStroke.Transparency = 1.0
                blockActivationUntil = tick() + config.DisableAfterMove
                showNotification("Botón movido. Contorno desactivado.")
            end
        end
    end
end)

UserInputService.InputEnded:Connect(function(input, processed)
    if processed then return end
    if config.AIM_HOLD_MODE and isBindMatch(config.AIM_KEY, input) then
        if isTargeting then
            deactivateAiming()
        end
    end
end)

-- Initialization
createMobileGuiIfNeeded()
wireMobileButton()
showNotification("Aim Assist Pro")

RunService.RenderStepped:Connect(function()
    gameControllingCamera = (camera.CameraType ~= Enum.CameraType.Custom)
end)

player.CharacterRemoving:Connect(function()
    if isTargeting then deactivateAiming() end
    setMouseIconVisible(prevMouseIconEnabled)
end)

camera:GetPropertyChangedSignal("CameraType"):Connect(function()
    gameControllingCamera = (camera.CameraType ~= Enum.CameraType.Custom)
    if gameControllingCamera and UserInputService.MouseEnabled and not isTargeting and not menuOpen then
        pcall(function() UserInputService.MouseIconEnabled = prevMouseIconEnabled end)
    end
end)

Features & Information

**Script de Aim Assist Pro para Roblox** con menú configurable que ofrece apuntado automático, suavizado de cámara, resaltado y marcado de objetivos, además de teletransportación. En móviles funciona de forma limitada: solo incluye la función de *aimbot*, mientras que en PC se dispone de todas las opciones avanzadas.

Community Comments (0)

No comments yet for this script.

More Scripts for Universal Scripts