-- === Config === local defaultConfig = { Enabled = true, AimKey = Enum.KeyCode.Z, ToggleMode = true, StickyAim = true, AimPart = "HumanoidRootPart", --"Head" "UpperTorso" "RightLeg" "LeftLeg" "RightArm" "LeftArm" "LowerTorso" MaxDistance = 1000, StickyResetOnLose = true, ShowTargetUI = true, Prediction = { BaseFactor = 0.12, AirFactor = 0.05, Dynamic = true, DynamicScale = 0.1, Min = 0.02, Max = 0.25, UpdateRate = 0.1 }, Smoothing = { Enabled = true, --Presets: VerySmooth: [0.08, 0.02, 0.2] Smooth [0.2, 0.05, 0.6] Snappy [1, 0.2, 1] Adaptive = true, Value = 0.8, Min = 0.08, Max = 0.2, }, Checks = { Visible = true, Team = false, Alive = false, Knocked = true, }, HistoryMax = 10, VisibilityRate = 0.1, GUIUpdateRate = 0.1 } local Players = game:GetService("Players") local RunService = game:GetService("RunService") local UserInput = game:GetService("UserInputService") local LocalPlayer = Players.LocalPlayer local Camera = workspace.CurrentCamera if not LocalPlayer then LocalPlayer = Players.PlayerAdded:Wait() end local Config = setmetatable({}, { __index = defaultConfig, __newindex = function(_, key, value) defaultConfig[key] = value if key == "AimKey" or key == "ToggleMode" or key == "StickyAim" then bindInputEvents() end end, }) local function lerp(a, b, t) return a + (b - a) * t end local function clamp(v, lo, hi) return math.max(lo, math.min(hi, v)) end local function safeGetChildOfClass(obj, className) return obj and obj:FindFirstChildOfClass(className) end local playerGui = LocalPlayer:WaitForChild("PlayerGui") local infoGui = Instance.new("ScreenGui") infoGui.Name = "AimlockInfoGui" infoGui.ResetOnSpawn = false infoGui.Parent = playerGui local infoFrame = Instance.new("Frame") infoFrame.Size = UDim2.new(0, 240, 0, 80) infoFrame.Position = UDim2.new(0.5, -120, 0, 50) infoFrame.BackgroundColor3 = Color3.fromRGB(0, 0, 0) infoFrame.BackgroundTransparency = 0.5 infoFrame.Visible = false infoFrame.Parent = infoGui local avatarImage = Instance.new("ImageLabel", infoFrame) avatarImage.Size = UDim2.new(0, 64, 0, 64) avatarImage.Position = UDim2.new(0, 5, 0, 5) avatarImage.BackgroundTransparency = 1 local nameLabel = Instance.new("TextLabel", infoFrame) nameLabel.Size = UDim2.new(0, 160, 0, 20) nameLabel.Position = UDim2.new(0, 74, 0, 5) nameLabel.BackgroundTransparency = 1 nameLabel.TextColor3 = Color3.new(1, 1, 1) nameLabel.TextXAlignment = Enum.TextXAlignment.Left nameLabel.Text = "" local healthLabel = Instance.new("TextLabel", infoFrame) healthLabel.Size = UDim2.new(0, 160, 0, 20) healthLabel.Position = UDim2.new(0, 74, 0, 30) healthLabel.BackgroundTransparency = 1 healthLabel.TextColor3 = Color3.new(1, 1, 1) healthLabel.TextXAlignment = Enum.TextXAlignment.Left healthLabel.Text = "" local knockedLabel = Instance.new("TextLabel", infoFrame) knockedLabel.Size = UDim2.new(0, 160, 0, 20) knockedLabel.Position = UDim2.new(0, 74, 0, 55) knockedLabel.BackgroundTransparency = 1 knockedLabel.TextColor3 = Color3.new(1, 1, 1) knockedLabel.TextXAlignment = Enum.TextXAlignment.Left knockedLabel.Text = "" local thumbCache = {} local lastGUIUpdate = 0 local function safeThumbnailForPlayer(p) if thumbCache[p] then return thumbCache[p] end local ok, thumb = pcall(function() return Players:GetUserThumbnailAsync(p.UserId, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size100x100) end) if ok and thumb then thumbCache[p] = thumb return thumb end return "" end local function updateInfoGui(target) if not Config.ShowTargetUI then infoFrame.Visible = false return end local now = tick() if now - lastGUIUpdate < Config.GUIUpdateRate then return end lastGUIUpdate = now if target and target.Character then infoFrame.Visible = true avatarImage.Image = safeThumbnailForPlayer(target) nameLabel.Text = ("Name: %s"):format(target.DisplayName or target.Name or "Unknown") local hum = safeGetChildOfClass(target.Character, "Humanoid") if hum then healthLabel.Text = ("Health: %d/%d"):format(math.max(0, math.floor(hum.Health)), math.floor(hum.MaxHealth or 0)) knockedLabel.Text = (hum.Health < 18) and "Knocked: Yes" or "Knocked: No" else healthLabel.Text = "" knockedLabel.Text = "" end else infoFrame.Visible = false end end local rayParams = RaycastParams.new() rayParams.FilterType = Enum.RaycastFilterType.Blacklist local visibilityCache = setmetatable({}, { __mode = "k" }) local histories = setmetatable({}, { __mode = "k" }) local currentTarget = nil local aiming = false local visibilityUnlocked = false local inputBeginConn, inputEndConn, renderConn function bindInputEvents() if inputBeginConn then inputBeginConn:Disconnect() end if inputEndConn then inputEndConn:Disconnect() end inputBeginConn = UserInput.InputBegan:Connect(function(input, gameProcessed) if gameProcessed then return end if input.KeyCode == Config.AimKey then if visibilityUnlocked then if currentTarget and histories[currentTarget] then histories[currentTarget] = nil end currentTarget = nil visibilityUnlocked = false aiming = false updateInfoGui(nil) return end if Config.StickyAim then if Config.ToggleMode then aiming = not aiming else aiming = true end if not aiming then if currentTarget and histories[currentTarget] then histories[currentTarget] = nil end currentTarget = nil visibilityUnlocked = false updateInfoGui(nil) end else aiming = true end end end) inputEndConn = UserInput.InputEnded:Connect(function(input, gameProcessed) if gameProcessed then return end if input.KeyCode == Config.AimKey then if Config.StickyAim and Config.ToggleMode then return end if currentTarget and histories[currentTarget] then histories[currentTarget] = nil end aiming = false currentTarget = nil visibilityUnlocked = false updateInfoGui(nil) end end) end bindInputEvents() local function isAlive(player) if not Config.Checks.Alive then return true end local hum = safeGetChildOfClass(player.Character, "Humanoid") return hum and hum.Health > 0 end local function isTeammate(player) if not Config.Checks.Team then return false end return LocalPlayer.Team and player.Team == LocalPlayer.Team end local function isKnocked(player) if not Config.Checks.Knocked then return false end local hum = safeGetChildOfClass(player.Character, "Humanoid") return hum and (hum.Health < 18) end local function isVisible(player, partName) local now = tick() local cached = visibilityCache[player] if cached and (now - cached.lastCheck) < Config.VisibilityRate then return cached.value end local result = false if not Config.Checks.Visible then result = true else local char = player.Character local part = char and char:FindFirstChild(partName) if part and Camera and Camera.CFrame then local origin = Camera.CFrame.Position local direction = part.Position - origin rayParams.FilterDescendantsInstances = {LocalPlayer.Character, char} local hit = workspace:Raycast(origin, direction.Unit * direction.Magnitude, rayParams) result = (hit == nil) else result = false end end visibilityCache[player] = { lastCheck = now, value = result } return result end local function worldDistance(player) local a = player.Character and player.Character:FindFirstChild(Config.AimPart) local b = LocalPlayer.Character and LocalPlayer.Character:FindFirstChild(Config.AimPart) if not a or not b then return math.huge end return (a.Position - b.Position).Magnitude end local function screenDistance(player) local part = player.Character and player.Character:FindFirstChild(Config.AimPart) if not part or not Camera then return math.huge end local screenPos, onScreen = Camera:WorldToScreenPoint(part.Position) if not onScreen then return math.huge end local mouseLocation = UserInput:GetMouseLocation() return (Vector2.new(screenPos.X, screenPos.Y) - Vector2.new(mouseLocation.X, mouseLocation.Y)).Magnitude end local lastPredictionUpdate = 0 local function recordHistory(player) local part = player.Character and player.Character:FindFirstChild(Config.AimPart) if not part then return end histories[player] = histories[player] or {} table.insert(histories[player], 1, { vel = part.Velocity, time = tick() }) while #histories[player] > Config.HistoryMax do table.remove(histories[player]) end end local function predictPosition(player, part) local now = tick() local vel = part.Velocity local factor = Config.Prediction.BaseFactor local hum = safeGetChildOfClass(player.Character, "Humanoid") local state = hum and hum:GetState() if state == Enum.HumanoidStateType.Freefall or state == Enum.HumanoidStateType.Jumping then factor = Config.Prediction.AirFactor elseif Config.Prediction.Dynamic and histories[player] and (now - (lastPredictionUpdate or 0) > Config.Prediction.UpdateRate) then local sumAcc = Vector3.new(0, 0, 0) local count = 0 local hist = histories[player] for i = 1, (#hist - 1) do local dv = hist[i].vel - hist[i + 1].vel local dt = hist[i].time - hist[i + 1].time if dt and dt > 0 then sumAcc = sumAcc + (dv / dt) count = count + 1 end end if count > 0 then local avgAcc = sumAcc / count vel = vel + avgAcc * Config.Prediction.BaseFactor * Config.Prediction.DynamicScale end lastPredictionUpdate = now end factor = clamp(factor, Config.Prediction.Min, Config.Prediction.Max) return part.Position + vel * factor end local function gatherCandidates() local candidates = {} for _, p in ipairs(Players:GetPlayers()) do if p ~= LocalPlayer and p.Character and p.Character.Parent then if isAlive(p) and not isTeammate(p) and not isKnocked(p) then local d = worldDistance(p) if d <= Config.MaxDistance and isVisible(p, Config.AimPart) then table.insert(candidates, p) end end end end return candidates end local function chooseClosestToCursor(list) local best, bestDist = nil, math.huge for _, p in ipairs(list) do local sd = screenDistance(p) if sd < bestDist then bestDist = sd best = p end end return best end local function getSmoothingAlpha(dt) if not Config.Smoothing.Enabled then return 1 end local alpha = Config.Smoothing.Value * dt * 60 if Config.Smoothing.Adaptive and currentTarget then local distFactor = clamp(worldDistance(currentTarget) / Config.MaxDistance, 0, 1) local adaptiveAlpha = lerp(Config.Smoothing.Max, Config.Smoothing.Min, distFactor) alpha = adaptiveAlpha * dt * 60 end return clamp(alpha, Config.Smoothing.Min, Config.Smoothing.Max) end local function aimAtPosition(position, dt) if not position or not Camera then return end local origin = Camera.CFrame.Position local goal = CFrame.new(origin, position) if Config.Smoothing.Enabled then local alpha = getSmoothingAlpha(dt) Camera.CFrame = Camera.CFrame:Lerp(goal, alpha) else Camera.CFrame = goal end end renderConn = RunService.RenderStepped:Connect(function(dt) if visibilityUnlocked and currentTarget then if isAlive(currentTarget) and (not isKnocked(currentTarget)) and (not Config.Checks.Visible or isVisible(currentTarget, Config.AimPart)) then aiming = true visibilityUnlocked = false updateInfoGui(currentTarget) end end if not Config.Enabled or not aiming then updateInfoGui(currentTarget) return end if not currentTarget then local candidates = gatherCandidates() currentTarget = chooseClosestToCursor(candidates) if not currentTarget then updateInfoGui(nil) return end end if not isAlive(currentTarget) or isKnocked(currentTarget) then if histories[currentTarget] then histories[currentTarget] = nil end currentTarget = nil updateInfoGui(nil) return end if Config.Checks.Visible and not isVisible(currentTarget, Config.AimPart) then aiming = false visibilityUnlocked = true updateInfoGui(currentTarget) return end updateInfoGui(currentTarget) if currentTarget and currentTarget.Character then local part = currentTarget.Character:FindFirstChild(Config.AimPart) if part then recordHistory(currentTarget) local predicted = predictPosition(currentTarget, part) aimAtPosition(predicted, dt) else if histories[currentTarget] then histories[currentTarget] = nil end if Config.StickyResetOnLose then currentTarget = nil end updateInfoGui(nil) end else if currentTarget and histories[currentTarget] then histories[currentTarget] = nil end currentTarget = nil updateInfoGui(nil) end end) return Config