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 TweenService = game:GetService("TweenService") local player = Players.LocalPlayer local camera = workspace.CurrentCamera local defaultConfig = { MAX_VIEW_ANGLE = 90, SUAVIZADO = 1.0, MAX_PREDICTION_DISTANCE = 1.5, PREDICTION_TIME = 0.2, AIM_PREDICT_TIME = 0.2, PREDICTION_SUAVIZADO = 1.0, MAX_AIM_DISTANCE = 9999, AIM_KEY = Enum.KeyCode.R, HIGHLIGHT_KEY = Enum.KeyCode.T, MENU_KEY = Enum.KeyCode.RightControl, TELEPORT_KEY = Enum.KeyCode.C, HIGHLIGHT_COLOR = Color3.new(0, 1, 0), CAMERA_OFFSET = Vector3.new(0, 2.5, 0), -- Ajuste: predeterminado Y = 2.5 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, KeepAimingAfterDeathSeconds = 1.0, ENABLE_AIMING = true, -- toggle global (no tocar) AIM_HOLD_MODE = true, -- true = mantener tecla para apuntar; false = presionar para alternar } local config = {} for k,v in pairs(defaultConfig) do config[k] = v end local humanoid = nil local targetCharacter = nil local highlight = nil local isTargeting = false local menuGui = nil local menuOpen = false local currentNotification = nil local sliderRefs = {} local settingsBoxes = {} local keysBoxes = {} local colorBtn = nil local dragLocked = false local screenGuiMobile = nil local aimButton = nil local dragStroke = nil local longPressTimer = nil local longPressTriggered = false local blockActivationUntil = 0 local cameraUpdateConnection = nil local mobileMiraBillboard = nil local distanciaCamaraInicial = 12 local predictedPositions = setmetatable({}, { __mode = "k" }) local menuInputConn = nil local targetInfoUpdater = nil local aimingThread = nil local gameControllingCamera = false local prevMouseIconEnabled = UserInputService.MouseIconEnabled -- Cursor personalizado variables (ajustables) local customCursorConn = nil local customCursorGui = nil local customCursorFrame = nil local CUSTOM_CURSOR_SIZE = 16 -- tamaño del cursor/mira en px local CUSTOM_CURSOR_TRANSPARENCY = 0.35 -- transparencia del cursor/mira local CUSTOM_CURSOR_COLOR = Color3.fromRGB(255,255,255) -- color blanco (puedes cambiarlo) local CURSOR_DISPLAY_ORDER = 1000000 -- muy alto para intentar estar por encima de la interfaz local aimModeBtn = nil -- referencia al botón de modo de apuntado (en menú) 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 -- bindLabel: devuelve etiqueta legible para KeyCode o UserInputType (mouse) 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 -- Comprueba si el input coincide con el bind (acepta KeyCode o UserInputType) 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 label.AutoLocalize = false 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 -- Evitar que el cambio de CameraType vuelva a mostrar el cursor mientras estemos apuntando o con menú abierto 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) RunService.RenderStepped:Connect(function() gameControllingCamera = (camera.CameraType ~= Enum.CameraType.Custom) 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 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 userToInternalSmoothness(userVal) local u = math.clamp(tonumber(userVal) or 0, 0, 10) return (u / 10) * 0.7 end local function frameBlendFromSuavizado(dt) local rot = userToInternalSmoothness(config.SUAVIZADO or 0) local base = 1 - rot local alpha = 1 - math.pow(1 - base, math.clamp(dt * 60, 0, 1)) return alpha end local function userPredToInternalSmoothness(userVal) local u = math.clamp(tonumber(userVal) or 0, 0, 10) return (u / 10) * 0.9 end local function frameBlendFromPredictionSuavizado(dt) local rot = userPredToInternalSmoothness(config.PREDICTION_SUAVIZADO or 0) local base = 1 - rot local alpha = 1 - math.pow(1 - base, math.clamp(dt * 60, 0, 1)) return alpha end local function smoothAimAtCharacterFollowPlayer(char, dt) if not char or not player.Character then return end local hrp = char:FindFirstChild("HumanoidRootPart") local playerRoot = player.Character and player.Character:FindFirstChild("HumanoidRootPart") if not hrp or not playerRoot then return end local vel = hrp.Velocity or Vector3.zero local rawPredictedPosition = hrp.Position + vel * (config.AIM_PREDICT_TIME or 0.2) local offset = rawPredictedPosition - hrp.Position if offset.Magnitude > config.MAX_PREDICTION_DISTANCE then offset = offset.Unit * config.MAX_PREDICTION_DISTANCE rawPredictedPosition = hrp.Position + offset end local prevPred = predictedPositions[char] if not prevPred then prevPred = rawPredictedPosition end local predAlpha = frameBlendFromPredictionSuavizado(dt) local predictedPosition = prevPred:Lerp(rawPredictedPosition, predAlpha) predictedPositions[char] = predictedPosition 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 - predictedPosition).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 = (predictedPosition - posicionFinal).Unit local currentLook = camera.CFrame.LookVector local alpha = frameBlendFromSuavizado(dt) local lerpedLook if alpha >= 0.9999 then lerpedLook = desiredLook elseif alpha <= 0.0001 then lerpedLook = currentLook else lerpedLook = currentLook:Lerp(desiredLook, alpha) end camera.CFrame = CFrame.new(posicionFinal, posicionFinal + lerpedLook) 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 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 * -3 playerRoot.CFrame = CFrame.new(hrp.Position + back + Vector3.new(0,2.5,0)) showNotification("¡Teletransportado detrás de "..(targetCharacter.Name or "objetivo").."!") 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 barStroke = Instance.new("UIStroke", bar); barStroke.Transparency = 1 -- contorno removido (invisible) 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 = 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 if aimModeBtn and aimModeBtn.Parent then aimModeBtn.Text = config.AIM_HOLD_MODE and "Mantener" or "Alternar" end end end -- Manejo del cursor personalizado (se crea en su propio ScreenGui para DisplayOrder alto) local function createCustomCursor() -- si ya existe, limpiamos 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 = CUSTOM_CURSOR_COLOR frame.BackgroundTransparency = CUSTOM_CURSOR_TRANSPARENCY frame.ZIndex = CURSOR_DISPLAY_ORDER + 1 local ccCorner = Instance.new("UICorner", frame); ccCorner.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) -- ocultar cursor del sistema (si aplicable) 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 -- restaurar cursor del sistema según estado 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,520) frame.Position = UDim2.new(0.5, -210, 0.5, -260) frame.BackgroundColor3 = Color3.fromRGB(35,38,60) Instance.new("UICorner", frame).CornerRadius = UDim.new(0,18) local frameStroke = Instance.new("UIStroke", frame); frameStroke.Transparency = 1 -- contorno removido (invisible) 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, 420) 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 scrollStroke = Instance.new("UIStroke", scroll); scrollStroke.Transparency = 1 -- contorno removido (invisible) 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 (no lo quitamos) 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 local 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 = Color3.fromRGB(70,70,70); toggleBtn.TextColor3 = Color3.new(1,1,1) toggleBtn.Font = Enum.Font.GothamBold; toggleBtn.TextSize = 14 toggleBtn.Text = config.ENABLE_AIMING and "ON" or "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 "ON" or "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 = Color3.fromRGB(70,70,70); aimModeBtn.TextColor3 = Color3.new(1,1,1) 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) settingsBoxes = {} local settings = { {"Ángulo Máximo", "MAX_VIEW_ANGLE", 0, 180, 1}, {"Suavizado (0..10)", "SUAVIZADO", 0, 10, 0.1}, {"Distancia Predicción", "MAX_PREDICTION_DISTANCE", 0, 100, 0.1}, {"Segundos tras muerte", "PREDICTION_TIME", 0, 10, 0.1}, {"Suavizado Predicción (0..10)", "PREDICTION_SUAVIZADO", 0, 10, 0.1}, {"Distancia Máxima Apuntado", "MAX_AIM_DISTANCE", 1, 99999, 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]]) local corner = Instance.new("UICorner", inputBox); corner.CornerRadius = UDim.new(0,8) local stroke = Instance.new("UIStroke", inputBox); stroke.Transparency = 1 -- contorno removido (invisible) inputBox.FocusLost:Connect(function() local newVal = tonumber(inputBox.Text) if newVal then newVal = math.clamp(newVal, set[3], set[4]) config[set[2]] = newVal inputBox.Text = tostring(newVal) else inputBox.Text = 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) 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) local colorStroke = Instance.new("UIStroke", colorBtn); colorStroke.Transparency = 1 -- contorno removido (invisible) 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"}, } 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) local kbStroke = Instance.new("UIStroke", keyBtn); kbStroke.Transparency = 1 -- contorno removido (invisible) keyBtn.MouseButton1Click:Connect(function() keyBtn.Text = "..." local conn conn = UserInputService.InputBegan:Connect(function(input) -- Detectar teclado y mouse (MouseButton1/2/3) 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 local infoContainer = Instance.new("Frame", scroll) infoContainer.Size = UDim2.new(1, -24, 0, 110) infoContainer.BackgroundTransparency = 0 infoContainer.BackgroundColor3 = Color3.fromRGB(28,30,44) infoContainer.ClipsDescendants = true local infoCorner = Instance.new("UICorner", infoContainer); infoCorner.CornerRadius = UDim.new(0,10) local infoStroke = Instance.new("UIStroke", infoContainer); infoStroke.Transparency = 1 -- contorno removido (invisible) local infoTitle = Instance.new("TextLabel", infoContainer) infoTitle.Size = UDim2.new(1, -16, 0, 22) infoTitle.Position = UDim2.new(0, 8, 0, 6) infoTitle.BackgroundTransparency = 1 infoTitle.Font = Enum.Font.GothamBold infoTitle.Text = "Objetivo actual" infoTitle.TextColor3 = Color3.new(1,1,1) infoTitle.TextSize = 14 infoTitle.TextXAlignment = Enum.TextXAlignment.Center local ROW_LEFT_PAD = 32 local ROW_RIGHT_PAD = 30 local BUTTON_WIDTH = 70 local LABEL_WIDTH = 98 local VALUE_WIDTH = 115 local function makeInfoRow(parent, y, labelText, valueText) local row = Instance.new("Frame", parent) row.Size = UDim2.new(1, -16, 0, 24) row.Position = UDim2.new(0, 8, 0, y) row.BackgroundTransparency = 1 local lbl = Instance.new("TextLabel", row) lbl.Size = UDim2.new(0, LABEL_WIDTH, 1, 0) lbl.Position = UDim2.new(0, ROW_LEFT_PAD, 0, 0) lbl.BackgroundTransparency = 1 lbl.Font = Enum.Font.Gotham lbl.Text = labelText lbl.TextColor3 = Color3.new(1,1,1) lbl.TextSize = 13 lbl.TextXAlignment = Enum.TextXAlignment.Left lbl.TextWrapped = false local val = Instance.new("TextLabel", row) val.Size = UDim2.new(0, VALUE_WIDTH, 1, 0) val.Position = UDim2.new(0, ROW_LEFT_PAD + LABEL_WIDTH + 6, 0, 0) val.BackgroundTransparency = 1 val.Font = Enum.Font.Gotham val.Text = valueText or "-" val.TextColor3 = Color3.new(0.85,0.85,0.85) val.TextSize = 13 val.TextXAlignment = Enum.TextXAlignment.Left val.TextWrapped = false val.ClipsDescendants = true local copyBtn = Instance.new("TextButton", row) copyBtn.Size = UDim2.new(0, BUTTON_WIDTH, 0, 22) copyBtn.Position = UDim2.new(1, -BUTTON_WIDTH - ROW_RIGHT_PAD, 0.5, -11) copyBtn.BackgroundColor3 = Color3.fromRGB(75,85,120) copyBtn.TextColor3 = Color3.new(1,1,1) copyBtn.Font = Enum.Font.GothamBold copyBtn.TextSize = 13 copyBtn.Text = "Copiar" Instance.new("UICorner", copyBtn).CornerRadius = UDim.new(0,6) local cbStroke = Instance.new("UIStroke", copyBtn); cbStroke.Transparency = 1 -- contorno removido (invisible) copyBtn.MouseButton1Click:Connect(function() local textToCopy = val.Text or "" pcall(function() setclipboard(textToCopy) end) showNotification("Copiado: "..(textToCopy ~= "" and textToCopy or "-")) end) return lbl, val, copyBtn end local nameLbl, nameVal, nameCopy = makeInfoRow(infoContainer, 34, "Nombre:", "-") local displayLbl, displayVal, displayCopy = makeInfoRow(infoContainer, 34 + 26, "DisplayName:", "-") local idLbl, idVal, idCopy = makeInfoRow(infoContainer, 34 + 52, "UserId:", "-") local function updateTargetInfo() local tgt = targetCharacter if tgt and tgt.Parent then local ply = Players:GetPlayerFromCharacter(tgt) if ply then nameVal.Text = cropText(ply.Name, 13) displayVal.Text = cropText(ply.DisplayName, 18) idVal.Text = cropText(tostring(ply.UserId), 11) else nameVal.Text = cropText(tgt.Name, 13) displayVal.Text = "-" idVal.Text = "-" end else nameVal.Text = "-" displayVal.Text = "-" idVal.Text = "-" end end targetInfoUpdater = RunService.Heartbeat:Connect(updateTargetInfo) 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) local resetStroke = Instance.new("UIStroke", resetBtn); resetStroke.Transparency = 1 -- contorno removido (invisible) resetBtn.MouseButton1Click:Connect(function() for k,v in pairs(defaultConfig) do config[k] = typeof(v) == "Vector3" and v + Vector3.zero or v 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) local closeStroke = Instance.new("UIStroke", closeBtn); closeStroke.Transparency = 1 -- contorno removido (invisible) closeBtn.MouseButton1Click:Connect(function() -- destruir cursor personalizado si existe destroyCustomCursor() if menuGui then menuGui:Destroy(); menuGui = nil end menuOpen = false if targetInfoUpdater then targetInfoUpdater:Disconnect(); targetInfoUpdater = nil end if isTargeting then setMouseIconVisible(false) else setMouseIconVisible(prevMouseIconEnabled) end end) -- crear cursor personalizado (en su ScreenGui separado y con DisplayOrder alto) createCustomCursor() menuGui = gui refreshMenuUI() end -- El resto igual, no hay input handler para el scroll local targetDiedConnection = nil local targetAncestryConnection = nil 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" -- usar el mismo tamaño y transparencia que el cursor personalizado 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 = CUSTOM_CURSOR_COLOR point.BackgroundTransparency = CUSTOM_CURSOR_TRANSPARENCY Instance.new("UICorner", point).CornerRadius = UDim.new(1,0) end 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 if UserInputService.MouseEnabled then prevMouseIconEnabled = UserInputService.MouseIconEnabled -- solo ocultar el cursor del sistema si el menú NO está abierto; -- si el menú está abierto, dejamos el cursor personalizado visible (el menú crea/destroza su propio cursor) 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 -- Forzar ocultado del cursor SOLO si el menú NO está abierto. if UserInputService.MouseEnabled and not menuOpen then pcall(function() UserInputService.MouseIconEnabled = false end) end smoothAimAtCharacterFollowPlayer(targetCharacter, dt) end) end) cleanTargetConnections() local hum = targetCharacter:FindFirstChildOfClass("Humanoid") local thisTarget = targetCharacter if hum then targetDiedConnection = hum.Died:Connect(function() delay(config.PREDICTION_TIME or 0.2, function() if targetCharacter == thisTarget then local h = thisTarget and thisTarget:FindFirstChildOfClass("Humanoid") if not h or (h and h.Health <= 0) then isTargeting = false destroyMobileMira() if aimingThread then aimingThread:Disconnect(); aimingThread = nil end camera.CameraType = Enum.CameraType.Custom targetCharacter = nil setMouseIconVisible(prevMouseIconEnabled) end end end) end) end targetAncestryConnection = thisTarget.AncestryChanged:Connect(function(child, parent) if not parent or not child:IsDescendantOf(workspace) then isTargeting = false targetCharacter = nil destroyMobileMira() if aimingThread then aimingThread:Disconnect(); aimingThread = nil end camera.CameraType = Enum.CameraType.Custom cleanTargetConnections() setMouseIconVisible(prevMouseIconEnabled) end end) end local function deactivateAiming() isTargeting = false camera.CameraType = Enum.CameraType.Custom targetCharacter = nil destroyMobileMira() if aimingThread then aimingThread:Disconnect(); aimingThread = 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 -- Centralizamos la detección de inputs para acciones (acepta binds de teclado o mouse) UserInputService.InputBegan:Connect(function(input, processed) if processed then return end -- AIM_KEY handling: depende del modo AIM_HOLD_MODE if isBindMatch(config.AIM_KEY, input) then if config.AIM_HOLD_MODE then -- modo "Mantener": iniciar apuntado en InputBegan (se desenicia en InputEnded) if not isTargeting then activateAiming() end else -- modo "Alternar": presionar cambia estado 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 -- el menú crea su cursor personalizado else -- cerrar menú 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 teleportBehindTarget() end return end -- lógica de mover boton movil cuando está dragLocked (permite inputs touch/mouse) 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) -- En modo "Mantener" debemos escuchar InputEnded para detectar cuando el usuario suelta la tecla/mouse y desactivar apuntado. 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) UserInputService.InputChanged:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton2 and not menuOpen then createMenuGui() menuOpen = true -- menú se encarga del cursor personalizado end end) 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)--[[ Aim Assist Pro UI con Scroll Simple y 100% Funcional - El scroll del mouse dentro del menú de configuración es nativo y sin interferencias. - TODO el sistema de scroll custom (InputChanged/TweenService/CanvasPosition) ha sido removido. - El ScrollBar del ScrollingFrame funciona como Roblox estándar: puedes moverlo con rueda del mouse, arrastrar el bar o con touch naturalmente. - Mantiene todas tus mejoras de UI, displayname, y botones. - Cambios recientes: * Se quitaron UIStroke visibles (bordes) en la UI (se hacen transparentes). * Cursor personalizado (configuración) ahora puede mostrarse por encima de la interfaz (DisplayOrder alto). * Predeterminado de desplazamiento Y ajustado a 2.5. * Las teclas en el menú ahora aceptan teclas del mouse (MouseButton1/2/3) además de teclas del teclado. * Se agregó un toggle global para activar/desactivar el sistema de apuntado. * Se añadió opción para elegir modo de apuntado: "Mantener" (hold mientras mantienes la tecla) o "Alternar" (press para activar/desactivar). * Cursor personalizado y mira móvil usan mismo tamaño y transparencia configurables por constantes. ]] 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 TweenService = game:GetService("TweenService") local player = Players.LocalPlayer local camera = workspace.CurrentCamera local defaultConfig = { MAX_VIEW_ANGLE = 90, SUAVIZADO = 1.0, MAX_PREDICTION_DISTANCE = 1.5, PREDICTION_TIME = 0.2, AIM_PREDICT_TIME = 0.2, PREDICTION_SUAVIZADO = 1.0, MAX_AIM_DISTANCE = 9999, AIM_KEY = Enum.KeyCode.R, HIGHLIGHT_KEY = Enum.KeyCode.T, MENU_KEY = Enum.KeyCode.RightControl, TELEPORT_KEY = Enum.KeyCode.C, HIGHLIGHT_COLOR = Color3.new(0, 1, 0), CAMERA_OFFSET = Vector3.new(0, 2.5, 0), -- Ajuste: predeterminado Y = 2.5 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, KeepAimingAfterDeathSeconds = 1.0, ENABLE_AIMING = true, -- toggle global (no tocar) AIM_HOLD_MODE = true, -- true = mantener tecla para apuntar; false = presionar para alternar } local config = {} for k,v in pairs(defaultConfig) do config[k] = v end local humanoid = nil local targetCharacter = nil local highlight = nil local isTargeting = false local menuGui = nil local menuOpen = false local currentNotification = nil local sliderRefs = {} local settingsBoxes = {} local keysBoxes = {} local colorBtn = nil local dragLocked = false local screenGuiMobile = nil local aimButton = nil local dragStroke = nil local longPressTimer = nil local longPressTriggered = false local blockActivationUntil = 0 local cameraUpdateConnection = nil local mobileMiraBillboard = nil local distanciaCamaraInicial = 12 local predictedPositions = setmetatable({}, { __mode = "k" }) local menuInputConn = nil local targetInfoUpdater = nil local aimingThread = nil local gameControllingCamera = false local prevMouseIconEnabled = UserInputService.MouseIconEnabled -- Cursor personalizado variables (ajustables) local customCursorConn = nil local customCursorGui = nil local customCursorFrame = nil local CUSTOM_CURSOR_SIZE = 16 -- tamaño del cursor/mira en px local CUSTOM_CURSOR_TRANSPARENCY = 0.35 -- transparencia del cursor/mira local CUSTOM_CURSOR_COLOR = Color3.fromRGB(255,255,255) -- color blanco (puedes cambiarlo) local CURSOR_DISPLAY_ORDER = 1000000 -- muy alto para intentar estar por encima de la interfaz local aimModeBtn = nil -- referencia al botón de modo de apuntado (en menú) 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 -- bindLabel: devuelve etiqueta legible para KeyCode o UserInputType (mouse) 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 -- Comprueba si el input coincide con el bind (acepta KeyCode o UserInputType) 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 label.AutoLocalize = false 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 -- Evitar que el cambio de CameraType vuelva a mostrar el cursor mientras estemos apuntando o con menú abierto 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) RunService.RenderStepped:Connect(function() gameControllingCamera = (camera.CameraType ~= Enum.CameraType.Custom) 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 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 userToInternalSmoothness(userVal) local u = math.clamp(tonumber(userVal) or 0, 0, 10) return (u / 10) * 0.7 end local function frameBlendFromSuavizado(dt) local rot = userToInternalSmoothness(config.SUAVIZADO or 0) local base = 1 - rot local alpha = 1 - math.pow(1 - base, math.clamp(dt * 60, 0, 1)) return alpha end local function userPredToInternalSmoothness(userVal) local u = math.clamp(tonumber(userVal) or 0, 0, 10) return (u / 10) * 0.9 end local function frameBlendFromPredictionSuavizado(dt) local rot = userPredToInternalSmoothness(config.PREDICTION_SUAVIZADO or 0) local base = 1 - rot local alpha = 1 - math.pow(1 - base, math.clamp(dt * 60, 0, 1)) return alpha end local function smoothAimAtCharacterFollowPlayer(char, dt) if not char or not player.Character then return end local hrp = char:FindFirstChild("HumanoidRootPart") local playerRoot = player.Character and player.Character:FindFirstChild("HumanoidRootPart") if not hrp or not playerRoot then return end local vel = hrp.Velocity or Vector3.zero local rawPredictedPosition = hrp.Position + vel * (config.AIM_PREDICT_TIME or 0.2) local offset = rawPredictedPosition - hrp.Position if offset.Magnitude > config.MAX_PREDICTION_DISTANCE then offset = offset.Unit * config.MAX_PREDICTION_DISTANCE rawPredictedPosition = hrp.Position + offset end local prevPred = predictedPositions[char] if not prevPred then prevPred = rawPredictedPosition end local predAlpha = frameBlendFromPredictionSuavizado(dt) local predictedPosition = prevPred:Lerp(rawPredictedPosition, predAlpha) predictedPositions[char] = predictedPosition 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 - predictedPosition).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 = (predictedPosition - posicionFinal).Unit local currentLook = camera.CFrame.LookVector local alpha = frameBlendFromSuavizado(dt) local lerpedLook if alpha >= 0.9999 then lerpedLook = desiredLook elseif alpha <= 0.0001 then lerpedLook = currentLook else lerpedLook = currentLook:Lerp(desiredLook, alpha) end camera.CFrame = CFrame.new(posicionFinal, posicionFinal + lerpedLook) 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 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 * -3 playerRoot.CFrame = CFrame.new(hrp.Position + back + Vector3.new(0,2.5,0)) showNotification("¡Teletransportado detrás de "..(targetCharacter.Name or "objetivo").."!") 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 barStroke = Instance.new("UIStroke", bar); barStroke.Transparency = 1 -- contorno removido (invisible) 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 = 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 if aimModeBtn and aimModeBtn.Parent then aimModeBtn.Text = config.AIM_HOLD_MODE and "Mantener" or "Alternar" end end end -- Manejo del cursor personalizado (se crea en su propio ScreenGui para DisplayOrder alto) local function createCustomCursor() -- si ya existe, limpiamos 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 = CUSTOM_CURSOR_COLOR frame.BackgroundTransparency = CUSTOM_CURSOR_TRANSPARENCY frame.ZIndex = CURSOR_DISPLAY_ORDER + 1 local ccCorner = Instance.new("UICorner", frame); ccCorner.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) -- ocultar cursor del sistema (si aplicable) 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 -- restaurar cursor del sistema según estado 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,520) frame.Position = UDim2.new(0.5, -210, 0.5, -260) frame.BackgroundColor3 = Color3.fromRGB(35,38,60) Instance.new("UICorner", frame).CornerRadius = UDim.new(0,18) local frameStroke = Instance.new("UIStroke", frame); frameStroke.Transparency = 1 -- contorno removido (invisible) 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, 420) 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 scrollStroke = Instance.new("UIStroke", scroll); scrollStroke.Transparency = 1 -- contorno removido (invisible) 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 (no lo quitamos) 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 local 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 = Color3.fromRGB(70,70,70); toggleBtn.TextColor3 = Color3.new(1,1,1) toggleBtn.Font = Enum.Font.GothamBold; toggleBtn.TextSize = 14 toggleBtn.Text = config.ENABLE_AIMING and "ON" or "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 "ON" or "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 = Color3.fromRGB(70,70,70); aimModeBtn.TextColor3 = Color3.new(1,1,1) 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) settingsBoxes = {} local settings = { {"Ángulo Máximo", "MAX_VIEW_ANGLE", 0, 180, 1}, {"Suavizado (0..10)", "SUAVIZADO", 0, 10, 0.1}, {"Distancia Predicción", "MAX_PREDICTION_DISTANCE", 0, 100, 0.1}, {"Segundos tras muerte", "PREDICTION_TIME", 0, 10, 0.1}, {"Suavizado Predicción (0..10)", "PREDICTION_SUAVIZADO", 0, 10, 0.1}, {"Distancia Máxima Apuntado", "MAX_AIM_DISTANCE", 1, 99999, 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]]) local corner = Instance.new("UICorner", inputBox); corner.CornerRadius = UDim.new(0,8) local stroke = Instance.new("UIStroke", inputBox); stroke.Transparency = 1 -- contorno removido (invisible) inputBox.FocusLost:Connect(function() local newVal = tonumber(inputBox.Text) if newVal then newVal = math.clamp(newVal, set[3], set[4]) config[set[2]] = newVal inputBox.Text = tostring(newVal) else inputBox.Text = 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) 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) local colorStroke = Instance.new("UIStroke", colorBtn); colorStroke.Transparency = 1 -- contorno removido (invisible) 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"}, } 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) local kbStroke = Instance.new("UIStroke", keyBtn); kbStroke.Transparency = 1 -- contorno removido (invisible) keyBtn.MouseButton1Click:Connect(function() keyBtn.Text = "..." local conn conn = UserInputService.InputBegan:Connect(function(input) -- Detectar teclado y mouse (MouseButton1/2/3) 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 local infoContainer = Instance.new("Frame", scroll) infoContainer.Size = UDim2.new(1, -24, 0, 110) infoContainer.BackgroundTransparency = 0 infoContainer.BackgroundColor3 = Color3.fromRGB(28,30,44) infoContainer.ClipsDescendants = true local infoCorner = Instance.new("UICorner", infoContainer); infoCorner.CornerRadius = UDim.new(0,10) local infoStroke = Instance.new("UIStroke", infoContainer); infoStroke.Transparency = 1 -- contorno removido (invisible) local infoTitle = Instance.new("TextLabel", infoContainer) infoTitle.Size = UDim2.new(1, -16, 0, 22) infoTitle.Position = UDim2.new(0, 8, 0, 6) infoTitle.BackgroundTransparency = 1 infoTitle.Font = Enum.Font.GothamBold infoTitle.Text = "Objetivo actual" infoTitle.TextColor3 = Color3.new(1,1,1) infoTitle.TextSize = 14 infoTitle.TextXAlignment = Enum.TextXAlignment.Center local ROW_LEFT_PAD = 32 local ROW_RIGHT_PAD = 30 local BUTTON_WIDTH = 70 local LABEL_WIDTH = 98 local VALUE_WIDTH = 115 local function makeInfoRow(parent, y, labelText, valueText) local row = Instance.new("Frame", parent) row.Size = UDim2.new(1, -16, 0, 24) row.Position = UDim2.new(0, 8, 0, y) row.BackgroundTransparency = 1 local lbl = Instance.new("TextLabel", row) lbl.Size = UDim2.new(0, LABEL_WIDTH, 1, 0) lbl.Position = UDim2.new(0, ROW_LEFT_PAD, 0, 0) lbl.BackgroundTransparency = 1 lbl.Font = Enum.Font.Gotham lbl.Text = labelText lbl.TextColor3 = Color3.new(1,1,1) lbl.TextSize = 13 lbl.TextXAlignment = Enum.TextXAlignment.Left lbl.TextWrapped = false local val = Instance.new("TextLabel", row) val.Size = UDim2.new(0, VALUE_WIDTH, 1, 0) val.Position = UDim2.new(0, ROW_LEFT_PAD + LABEL_WIDTH + 6, 0, 0) val.BackgroundTransparency = 1 val.Font = Enum.Font.Gotham val.Text = valueText or "-" val.TextColor3 = Color3.new(0.85,0.85,0.85) val.TextSize = 13 val.TextXAlignment = Enum.TextXAlignment.Left val.TextWrapped = false val.ClipsDescendants = true local copyBtn = Instance.new("TextButton", row) copyBtn.Size = UDim2.new(0, BUTTON_WIDTH, 0, 22) copyBtn.Position = UDim2.new(1, -BUTTON_WIDTH - ROW_RIGHT_PAD, 0.5, -11) copyBtn.BackgroundColor3 = Color3.fromRGB(75,85,120) copyBtn.TextColor3 = Color3.new(1,1,1) copyBtn.Font = Enum.Font.GothamBold copyBtn.TextSize = 13 copyBtn.Text = "Copiar" Instance.new("UICorner", copyBtn).CornerRadius = UDim.new(0,6) local cbStroke = Instance.new("UIStroke", copyBtn); cbStroke.Transparency = 1 -- contorno removido (invisible) copyBtn.MouseButton1Click:Connect(function() local textToCopy = val.Text or "" pcall(function() setclipboard(textToCopy) end) showNotification("Copiado: "..(textToCopy ~= "" and textToCopy or "-")) end) return lbl, val, copyBtn end local nameLbl, nameVal, nameCopy = makeInfoRow(infoContainer, 34, "Nombre:", "-") local displayLbl, displayVal, displayCopy = makeInfoRow(infoContainer, 34 + 26, "DisplayName:", "-") local idLbl, idVal, idCopy = makeInfoRow(infoContainer, 34 + 52, "UserId:", "-") local function updateTargetInfo() local tgt = targetCharacter if tgt and tgt.Parent then local ply = Players:GetPlayerFromCharacter(tgt) if ply then nameVal.Text = cropText(ply.Name, 13) displayVal.Text = cropText(ply.DisplayName, 18) idVal.Text = cropText(tostring(ply.UserId), 11) else nameVal.Text = cropText(tgt.Name, 13) displayVal.Text = "-" idVal.Text = "-" end else nameVal.Text = "-" displayVal.Text = "-" idVal.Text = "-" end end targetInfoUpdater = RunService.Heartbeat:Connect(updateTargetInfo) 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) local resetStroke = Instance.new("UIStroke", resetBtn); resetStroke.Transparency = 1 -- contorno removido (invisible) resetBtn.MouseButton1Click:Connect(function() for k,v in pairs(defaultConfig) do config[k] = typeof(v) == "Vector3" and v + Vector3.zero or v 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) local closeStroke = Instance.new("UIStroke", closeBtn); closeStroke.Transparency = 1 -- contorno removido (invisible) closeBtn.MouseButton1Click:Connect(function() -- destruir cursor personalizado si existe destroyCustomCursor() if menuGui then menuGui:Destroy(); menuGui = nil end menuOpen = false if targetInfoUpdater then targetInfoUpdater:Disconnect(); targetInfoUpdater = nil end if isTargeting then setMouseIconVisible(false) else setMouseIconVisible(prevMouseIconEnabled) end end) -- crear cursor personalizado (en su ScreenGui separado y con DisplayOrder alto) createCustomCursor() menuGui = gui refreshMenuUI() end -- El resto igual, no hay input handler para el scroll local targetDiedConnection = nil local targetAncestryConnection = nil 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" -- usar el mismo tamaño y transparencia que el cursor personalizado 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 = CUSTOM_CURSOR_COLOR point.BackgroundTransparency = CUSTOM_CURSOR_TRANSPARENCY Instance.new("UICorner", point).CornerRadius = UDim.new(1,0) end 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 if UserInputService.MouseEnabled then prevMouseIconEnabled = UserInputService.MouseIconEnabled -- solo ocultar el cursor del sistema si el menú NO está abierto; -- si el menú está abierto, dejamos el cursor personalizado visible (el menú crea/destroza su propio cursor) 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 -- Forzar ocultado del cursor SOLO si el menú NO está abierto. if UserInputService.MouseEnabled and not menuOpen then pcall(function() UserInputService.MouseIconEnabled = false end) end smoothAimAtCharacterFollowPlayer(targetCharacter, dt) end) end) cleanTargetConnections() local hum = targetCharacter:FindFirstChildOfClass("Humanoid") local thisTarget = targetCharacter if hum then targetDiedConnection = hum.Died:Connect(function() delay(config.PREDICTION_TIME or 0.2, function() if targetCharacter == thisTarget then local h = thisTarget and thisTarget:FindFirstChildOfClass("Humanoid") if not h or (h and h.Health <= 0) then isTargeting = false destroyMobileMira() if aimingThread then aimingThread:Disconnect(); aimingThread = nil end camera.CameraType = Enum.CameraType.Custom targetCharacter = nil setMouseIconVisible(prevMouseIconEnabled) end end end) end) end targetAncestryConnection = thisTarget.AncestryChanged:Connect(function(child, parent) if not parent or not child:IsDescendantOf(workspace) then isTargeting = false targetCharacter = nil destroyMobileMira() if aimingThread then aimingThread:Disconnect(); aimingThread = nil end camera.CameraType = Enum.CameraType.Custom cleanTargetConnections() setMouseIconVisible(prevMouseIconEnabled) end end) end local function deactivateAiming() isTargeting = false camera.CameraType = Enum.CameraType.Custom targetCharacter = nil destroyMobileMira() if aimingThread then aimingThread:Disconnect(); aimingThread = 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 -- Centralizamos la detección de inputs para acciones (acepta binds de teclado o mouse) UserInputService.InputBegan:Connect(function(input, processed) if processed then return end -- AIM_KEY handling: depende del modo AIM_HOLD_MODE if isBindMatch(config.AIM_KEY, input) then if config.AIM_HOLD_MODE then -- modo "Mantener": iniciar apuntado en InputBegan (se desenicia en InputEnded) if not isTargeting then activateAiming() end else -- modo "Alternar": presionar cambia estado 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 -- el menú crea su cursor personalizado else -- cerrar menú 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 teleportBehindTarget() end return end -- lógica de mover boton movil cuando está dragLocked (permite inputs touch/mouse) 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) -- En modo "Mantener" debemos escuchar InputEnded para detectar cuando el usuario suelta la tecla/mouse y desactivar apuntado. 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) UserInputService.InputChanged:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton2 and not menuOpen then createMenuGui() menuOpen = true -- menú se encarga del cursor personalizado end end) 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)