-- aimbott -- services -- local Players = game:GetService("Players") local RunService = game:GetService("RunService") local UserInputService = game:GetService("UserInputService") local Workspace = game:GetService("Workspace") -- settings -- local GUI_NAME = "aimbott" local SNAP_TIME = 0.1 local ESP_REFRESH = 0.2 local CAMERA_BIND = "aimbott_CameraLock" local MAX_Y_DIFFERENCE = 8 -- Maximum vertical difference in studs local CHECK_WALLS = true local PANEL_SIZE = UDim2.fromOffset(232, 164) local TOGGLE_SIZE = UDim2.fromOffset(58, 58) local PANEL_COLOR = Color3.fromRGB(22, 25, 34) local HEADER_COLOR = Color3.fromRGB(32, 36, 48) local BUTTON_OFF = Color3.fromRGB(48, 53, 66) local BUTTON_ON = Color3.fromRGB(48, 112, 174) local ENEMY_COLOR = Color3.fromRGB(255, 60, 65) local TEAM_COLOR = Color3.fromRGB(50, 255, 115) local NPC_COLOR = Color3.fromRGB(255, 220, 55) local LocalPlayer = Players.LocalPlayer local PlayerGui = LocalPlayer:WaitForChild("PlayerGui") -- cleanup -- local OldGui = PlayerGui:FindFirstChild(GUI_NAME) if OldGui then OldGui:Destroy() end RunService:UnbindFromRenderStep(CAMERA_BIND) local Connections = {} local function connect(signal, callback) local connection = signal:Connect(callback) table.insert(Connections, connection) return connection end -- gui -- local ScreenGui = Instance.new("ScreenGui") ScreenGui.Name = GUI_NAME ScreenGui.ResetOnSpawn = false ScreenGui.IgnoreGuiInset = true ScreenGui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling ScreenGui.Parent = PlayerGui local function addCorner(object, radius) local corner = Instance.new("UICorner") corner.CornerRadius = UDim.new(0, radius) corner.Parent = object return corner end local function addStroke(object, color, thickness) local stroke = Instance.new("UIStroke") stroke.Color = color stroke.Thickness = thickness stroke.Parent = object return stroke end -- main panel -- local MainPanel = Instance.new("Frame") MainPanel.Name = "MainPanel" MainPanel.Size = PANEL_SIZE MainPanel.AnchorPoint = Vector2.new(0.5, 0.5) MainPanel.Position = UDim2.new(0.5, 0, 0.5, -44) MainPanel.BackgroundColor3 = PANEL_COLOR MainPanel.BorderSizePixel = 0 MainPanel.Active = true MainPanel.Parent = ScreenGui addCorner(MainPanel, 12) addStroke(MainPanel, Color3.fromRGB(75, 83, 105), 1) -- header -- local Header = Instance.new("Frame") Header.Name = "Header" Header.Size = UDim2.new(1, 0, 0, 28) Header.BackgroundColor3 = HEADER_COLOR Header.BorderSizePixel = 0 Header.Active = true Header.Parent = MainPanel addCorner(Header, 10) local Title = Instance.new("TextLabel") Title.Name = "Title" Title.Size = UDim2.new(1, -20, 1, 0) Title.Position = UDim2.fromOffset(11, 0) Title.BackgroundTransparency = 1 Title.Text = GUI_NAME Title.TextColor3 = Color3.fromRGB(245, 247, 255) Title.TextSize = 15 Title.Font = Enum.Font.GothamBold Title.TextXAlignment = Enum.TextXAlignment.Left Title.Parent = Header -- buttons -- local function createButton(name, text, y) local button = Instance.new("TextButton") button.Name = name button.Size = UDim2.new(1, -24, 0, 32) button.Position = UDim2.fromOffset(12, y) button.BackgroundColor3 = BUTTON_OFF button.BorderSizePixel = 0 button.Text = text button.TextColor3 = Color3.fromRGB(245, 247, 255) button.TextSize = 13 button.Font = Enum.Font.GothamSemibold button.AutoButtonColor = true button.Parent = MainPanel addCorner(button, 8) return button end local AimbotButton = createButton( "AimbotButton", "Aimbot: OFF", 36 ) local ClosestButton = createButton( "ClosestAimbotButton", "Closest Aimbot: OFF", 76 ) local ESPButton = createButton( "ESPButton", "ESP: OFF", 116 ) -- rainbow toggle -- local ToggleButton = Instance.new("TextButton") ToggleButton.Name = "RainbowToggle" ToggleButton.Size = TOGGLE_SIZE ToggleButton.AnchorPoint = Vector2.new(0.5, 0.5) ToggleButton.Position = UDim2.new(0.5, 0, 0.5, 100) ToggleButton.BackgroundColor3 = Color3.new(1, 1, 1) ToggleButton.BorderSizePixel = 0 ToggleButton.Text = GUI_NAME ToggleButton.TextColor3 = Color3.new(1, 1, 1) ToggleButton.TextSize = 11 ToggleButton.Font = Enum.Font.GothamBold ToggleButton.TextStrokeTransparency = 0.25 ToggleButton.ZIndex = 10 ToggleButton.Active = true ToggleButton.Parent = ScreenGui addCorner(ToggleButton, 29) addStroke(ToggleButton, Color3.new(1, 1, 1), 1.5) local RainbowGradient = Instance.new("UIGradient") RainbowGradient.Color = ColorSequence.new({ ColorSequenceKeypoint.new(0.00, Color3.fromRGB(255, 35, 35)), ColorSequenceKeypoint.new(0.17, Color3.fromRGB(255, 150, 30)), ColorSequenceKeypoint.new(0.33, Color3.fromRGB(255, 245, 50)), ColorSequenceKeypoint.new(0.50, Color3.fromRGB(40, 255, 100)), ColorSequenceKeypoint.new(0.67, Color3.fromRGB(35, 150, 255)), ColorSequenceKeypoint.new(0.83, Color3.fromRGB(180, 55, 255)), ColorSequenceKeypoint.new(1.00, Color3.fromRGB(255, 35, 35)), }) RainbowGradient.Parent = ToggleButton -- dragging -- local function makeDraggable(handle, target, onClick) local dragging = false local activeType = nil local activeTouch = nil local dragStart = Vector2.zero local startTopLeft = Vector2.zero local moved = false local function beginDrag(input) local inputType = input.UserInputType if inputType ~= Enum.UserInputType.MouseButton1 and inputType ~= Enum.UserInputType.Touch then return end if dragging then return end dragging = true activeType = inputType activeTouch = inputType == Enum.UserInputType.Touch and input or nil moved = false dragStart = Vector2.new(input.Position.X, input.Position.Y) startTopLeft = target.AbsolutePosition end local function moveDrag(position) if not dragging then return end local currentPosition = Vector2.new(position.X, position.Y) local delta = currentPosition - dragStart if delta.Magnitude > 5 then moved = true end if not moved then return end local camera = Workspace.CurrentCamera local viewport = camera and camera.ViewportSize or Vector2.new(800, 600) local size = target.AbsoluteSize local parentPosition = Vector2.zero if target.Parent and target.Parent:IsA("GuiObject") then parentPosition = target.Parent.AbsolutePosition end local localStart = startTopLeft - parentPosition local maxX = math.max(0, viewport.X - size.X - parentPosition.X) local maxY = math.max(0, viewport.Y - size.Y - parentPosition.Y) local x = math.clamp(localStart.X + delta.X, 0, maxX) local y = math.clamp(localStart.Y + delta.Y, 0, maxY) target.Position = UDim2.fromOffset( x + size.X * target.AnchorPoint.X, y + size.Y * target.AnchorPoint.Y ) end local function finishDrag(input) if not dragging then return end if activeType == Enum.UserInputType.MouseButton1 then if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end elseif activeType == Enum.UserInputType.Touch then if input ~= activeTouch then return end else return end local wasClick = not moved dragging = false activeType = nil activeTouch = nil if wasClick and onClick then onClick() end end connect(handle.InputBegan, beginDrag) connect(UserInputService.InputChanged, function(input) if not dragging then return end if activeType == Enum.UserInputType.MouseButton1 and input.UserInputType == Enum.UserInputType.MouseMovement then moveDrag(input.Position) end end) connect(UserInputService.TouchMoved, function(input) if dragging and activeType == Enum.UserInputType.Touch and input == activeTouch then moveDrag(input.Position) end end) connect(UserInputService.InputEnded, function(input) if dragging and activeType == Enum.UserInputType.MouseButton1 then finishDrag(input) end end) connect(UserInputService.TouchEnded, function(input) if dragging and activeType == Enum.UserInputType.Touch then finishDrag(input) end end) end makeDraggable(Header, MainPanel) makeDraggable(ToggleButton, ToggleButton, function() MainPanel.Visible = not MainPanel.Visible end) -- team check -- local function isTeammate(player) if not player or player == LocalPlayer then return true end if player.Team ~= nil and LocalPlayer.Team ~= nil then return player.Team == LocalPlayer.Team end if player.Neutral or LocalPlayer.Neutral then return false end return player.TeamColor == LocalPlayer.TeamColor end -- model registry -- local TrackedModels = {} local HighlightsByModel = {} local function trackModelFromInstance(instance) local current = instance while current and current ~= Workspace do if current:IsA("Model") and current:FindFirstChildOfClass("Humanoid") then TrackedModels[current] = true return current end current = current.Parent end return nil end local function scanWorkspaceModels() for _, instance in ipairs(Workspace:GetDescendants()) do if instance:IsA("Model") and instance:FindFirstChildOfClass("Humanoid") then TrackedModels[instance] = true end end for _, player in ipairs(Players:GetPlayers()) do if player.Character then trackModelFromInstance(player.Character) end end end connect(Workspace.DescendantAdded, function(instance) trackModelFromInstance(instance) end) connect(Players.PlayerAdded, function(player) connect(player.CharacterAdded, function(character) trackModelFromInstance(character) end) end) for _, player in ipairs(Players:GetPlayers()) do connect(player.CharacterAdded, function(character) trackModelFromInstance(character) end) if player.Character then trackModelFromInstance(player.Character) end end scanWorkspaceModels() -- target validation -- local function getTargetInfo(model) if not model or not model:IsA("Model") or model == LocalPlayer.Character or not model:IsDescendantOf(Workspace) then return nil end local humanoid = model:FindFirstChildOfClass("Humanoid") if not humanoid or humanoid.Health <= 0 then return nil end local player = Players:GetPlayerFromCharacter(model) if player and isTeammate(player) then return nil end -- Aim at the head only. local head = model:FindFirstChild("Head") if not head or not head:IsA("BasePart") then return nil end -- Use the root part for distance and height checks. local root = model:FindFirstChild("HumanoidRootPart") local distancePart if root and root:IsA("BasePart") then distancePart = root elseif humanoid.RootPart then distancePart = humanoid.RootPart else distancePart = head end return model, humanoid, head, distancePart, player end -- line of sight -- local AimRayParams = RaycastParams.new() AimRayParams.FilterType = Enum.RaycastFilterType.Exclude AimRayParams.IgnoreWater = true local function hasLineOfSight(model, head) if not CHECK_WALLS then return true end local camera = Workspace.CurrentCamera if not camera then return false end local origin = camera.CFrame.Position local direction = head.Position - origin if direction.Magnitude < 0.001 then return true end local localCharacter = LocalPlayer.Character AimRayParams.FilterDescendantsInstances = localCharacter and {localCharacter} or {} local result = Workspace:Raycast( origin, direction, AimRayParams ) -- No obstruction, or the first hit belongs to the target. if not result then return true end return result.Instance:IsDescendantOf(model) end -- vertical level check -- local function getLocalPosition() local character = LocalPlayer.Character local root = character and character:FindFirstChild("HumanoidRootPart") if root and root:IsA("BasePart") then return root.Position end local camera = Workspace.CurrentCamera if camera then return camera.CFrame.Position end return nil end local function isTargetEligible(model) local validModel, humanoid, head, distancePart, player = getTargetInfo(model) if not validModel then return false end local localPosition = getLocalPosition() if not localPosition then return false end -- Reject targets too far above or below the player's level. local verticalDifference = math.abs( distancePart.Position.Y - localPosition.Y ) if verticalDifference > MAX_Y_DIFFERENCE then return false end -- Reject targets hidden behind walls or other obstructions. if not hasLineOfSight(validModel, head) then return false end return true, validModel, humanoid, head, distancePart, player end -- closest visible target -- local function findClosestTarget() local origin = getLocalPosition() if not origin then return nil end for _, player in ipairs(Players:GetPlayers()) do if player.Character then trackModelFromInstance(player.Character) end end local closestModel = nil local closestDistance = math.huge for model in pairs(TrackedModels) do local eligible, validModel, _, _, distancePart = isTargetEligible(model) if eligible and validModel and distancePart then local distance = ( distancePart.Position - origin ).Magnitude if distance < closestDistance then closestDistance = distance closestModel = validModel end end end return closestModel end -- aimbot modes -- local AimMode = "Off" local LockedModel = nil local CurrentTargetModel = nil local SnapStartTime = 0 local SnapStartCFrame = nil local function setAimMode(requestedMode) if AimMode == requestedMode then AimMode = "Off" else AimMode = requestedMode end LockedModel = nil CurrentTargetModel = nil SnapStartCFrame = nil if AimMode == "Lock" then LockedModel = findClosestTarget() end end -- camera tracking -- local function updateAimCamera() if AimMode == "Off" then CurrentTargetModel = nil SnapStartCFrame = nil return end local targetModel = nil if AimMode == "Lock" then -- Keep the selected target while it remains visible and valid. -- If it dies, goes behind a wall, or leaves the allowed Y level, -- choose the closest eligible target instead. if LockedModel then local eligible = isTargetEligible(LockedModel) if not eligible then LockedModel = nil end end if not LockedModel then LockedModel = findClosestTarget() end targetModel = LockedModel elseif AimMode == "Closest" then -- Reevaluate the closest visible target continuously. targetModel = findClosestTarget() end local camera = Workspace.CurrentCamera if not camera or not targetModel then CurrentTargetModel = nil SnapStartCFrame = nil return end local eligible, validModel, _, head = isTargetEligible(targetModel) if not eligible or not validModel or not head then if AimMode == "Lock" then LockedModel = nil end CurrentTargetModel = nil SnapStartCFrame = nil return end -- Restart the snap timer when the target changes. if CurrentTargetModel ~= targetModel then CurrentTargetModel = targetModel SnapStartTime = os.clock() SnapStartCFrame = camera.CFrame end local cameraPosition = camera.CFrame.Position local direction = head.Position - cameraPosition if direction.Magnitude < 0.001 then return end local desiredCFrame = CFrame.lookAt( cameraPosition, head.Position ) local elapsed = os.clock() - SnapStartTime local alpha = math.clamp(elapsed / SNAP_TIME, 0, 1) if SnapStartCFrame and alpha < 1 then local startRotation = SnapStartCFrame.Rotation local startCFrame = CFrame.new(cameraPosition) * startRotation camera.CFrame = startCFrame:Lerp(desiredCFrame, alpha) else -- Strictly track the target after the initial snap. camera.CFrame = desiredCFrame end end RunService:BindToRenderStep( CAMERA_BIND, Enum.RenderPriority.Camera.Value + 1, updateAimCamera ) -- esp -- local ESPEnabled = false local function destroyHighlight(model) local highlight = HighlightsByModel[model] if highlight then highlight:Destroy() HighlightsByModel[model] = nil end end local function clearAllHighlights() for model, highlight in pairs(HighlightsByModel) do highlight:Destroy() HighlightsByModel[model] = nil end end local function updateHighlight(model, color) local highlight = HighlightsByModel[model] if not highlight or not highlight.Parent then highlight = Instance.new("Highlight") highlight.Name = "aimbott_ESP" highlight.Adornee = model highlight.DepthMode = Enum.HighlightDepthMode.AlwaysOnTop highlight.FillTransparency = 0.68 highlight.OutlineTransparency = 0.05 highlight.Parent = model HighlightsByModel[model] = highlight end highlight.Adornee = model highlight.Enabled = true highlight.FillColor = color highlight.OutlineColor = color end local function refreshESP() for model in pairs(TrackedModels) do local inWorkspace = model:IsDescendantOf(Workspace) local humanoid = model:FindFirstChildOfClass("Humanoid") if not inWorkspace or not humanoid then destroyHighlight(model) TrackedModels[model] = nil elseif model == LocalPlayer.Character then destroyHighlight(model) elseif not ESPEnabled then destroyHighlight(model) else local player = Players:GetPlayerFromCharacter(model) local color = NPC_COLOR if player then if isTeammate(player) then color = TEAM_COLOR else color = ENEMY_COLOR end end updateHighlight(model, color) end end end task.spawn(function() while ScreenGui.Parent do refreshESP() task.wait(ESP_REFRESH) end end) -- button states -- local function updateButtonLabels() if AimMode == "Lock" then AimbotButton.Text = "Aimbot: ON" AimbotButton.BackgroundColor3 = BUTTON_ON else AimbotButton.Text = "Aimbot: OFF" AimbotButton.BackgroundColor3 = BUTTON_OFF end if AimMode == "Closest" then ClosestButton.Text = "Closest Aimbot: ON" ClosestButton.BackgroundColor3 = BUTTON_ON else ClosestButton.Text = "Closest Aimbot: OFF" ClosestButton.BackgroundColor3 = BUTTON_OFF end if ESPEnabled then ESPButton.Text = "ESP: ON" ESPButton.BackgroundColor3 = Color3.fromRGB(35, 130, 80) else ESPButton.Text = "ESP: OFF" ESPButton.BackgroundColor3 = BUTTON_OFF end end -- button events -- connect(AimbotButton.Activated, function() setAimMode("Lock") updateButtonLabels() end) connect(ClosestButton.Activated, function() setAimMode("Closest") updateButtonLabels() end) connect(ESPButton.Activated, function() ESPEnabled = not ESPEnabled if ESPEnabled then scanWorkspaceModels() refreshESP() else clearAllHighlights() end updateButtonLabels() end) -- rainbow animation -- connect(RunService.RenderStepped, function(deltaTime) RainbowGradient.Rotation = (RainbowGradient.Rotation + deltaTime * 90) % 360 end) -- cleanup -- connect(ScreenGui.Destroying, function() RunService:UnbindFromRenderStep(CAMERA_BIND) clearAllHighlights() for _, connection in ipairs(Connections) do connection:Disconnect() end end) updateButtonLabels()