Add in an advanced lock-on system with almost instant rotation in a 360 way.

Example Function:

```
function isfacing(object)
    if Settings.Autoparry.Toggle then
        if Settings.Autoparry.Facing then
            plrDirection = plr.Character.Head.CFrame.LookVector
            unit = (object.Head.CFrame.p - plr.Character.Head.CFrame.p).Unit
            value = math.pow((plrDirection - unit).Magnitude / 2, 2)
            if value >= Settings.Autoparry.Fov / 360 then
                return false
            else
                return true
            end
        else
            return true
        end
    end
end 
```

Script:

```
-- Enhanced LocalScript: Universal Player and Model Tracking with Smooth Lock-On and Accurate Prediction
-- Place this script in StarterPlayer > StarterPlayerScripts

--[[
    Features Added:
    - GUI for selecting specific body parts to target
    - Universal target selection (players and any model with a Humanoid)
    - Layered target selection based on FOV and distance
    - Shift Lock mode for instant rotation
    - Enhanced ESP indicators with customizable text and colors
    - Predictive tracking using Kalman Filter for accurate velocity estimation
    - Hitbox detection to ensure accurate targeting
    - Smooth lock-on using camera manipulation to prevent stuttering or jittering
    - Controllable movement while lock-on is active
    - Robust cleanup and event handling
--]]

-- Services
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local TweenService = game:GetService("TweenService")
local Workspace = game:GetService("Workspace")
local CurrentCamera = Workspace.CurrentCamera

-- Configuration Table
local CONFIG = {
    ROTATION = {
        Kp = 15,                 -- Proportional gain for PID
        Ki = 0.1,                -- Integral gain for PID (reduced for stability)
        Kd = 3,                  -- Derivative gain for PID
        MaxTorque = 50,          -- Maximum rotational force (not directly used now)
        MinThreshold = 0.01      -- Minimum angle threshold to apply rotation
    },
    ESP = {
        TextPrefix = "Targeted: ",
        Color = Color3.fromRGB(255, 0, 0),
        Size = UDim2.new(0, 150, 0, 50),
        Offset = Vector3.new(0, 2, 0)
    },
    TRACKING = {
        PredictionFactor = 0.3,  -- Seconds ahead to predict
        MaxDistance = 100,       -- Maximum distance to track a target
        RefreshInterval = 1,     -- Seconds between target searches
        MaxFOVAngle = 60         -- Maximum FOV angle for targeting
    },
    DEBUG = {
        Enabled = true,
        Verbose = true
    },
    GUI = {
        ScreenGuiName = "EnhancedLockOnESPGUI",
        FrameSize = UDim2.new(0, 220, 0, 400),
        FramePosition = UDim2.new(0, 10, 0.5, -200),
        ButtonSize = UDim2.new(1, -20, 0, 35),
        BodyParts = {
            "Left Arm",
            "Left Leg",
            "Torso",
            "Torso (Back)",
            "Head",
            "Right Leg",
            "Right Arm"
        },
        SelectedColor = Color3.fromRGB(70, 130, 180), -- Steel Blue
        UnselectedColor = Color3.fromRGB(50, 50, 50),
        HoverColor = Color3.fromRGB(100, 100, 100),
        TextColor = Color3.fromRGB(255, 255, 255),
        BackgroundColor = Color3.fromRGB(30, 30, 30),
        StrokeColor = Color3.fromRGB(255, 255, 255)
    },
    SHIFT_LOCK = {
        ToggleKey = Enum.KeyCode.LeftShift
    },
    TRACKING_SMOOTHNESS = {
        CameraLerpSpeed = 0.15    -- Speed of camera interpolation
    }
}

-- Variables
local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
local playerGui = player:WaitForChild("PlayerGui")
local camera = CurrentCamera

local trackedTarget = nil
local espIndicator = nil
local selectedBodyPart = "Torso (Back)"
local shiftLockMode = false

-- PID Controller State
local pidState = {
    integral = 0,
    previousError = 0
}

-- Kalman Filter State (Per Target)
local kalmanState = {}

-- Debug Function
local function debugLog(message, level)
    level = level or "INFO"
    if CONFIG.DEBUG.Enabled then
        if CONFIG.DEBUG.Verbose or level ~= "DEBUG" then
            print(string.format("[TrackerDebug][%s]: %s", level, message))
        end
    end
end

-- Helper Functions
local function hasHumanoid(model)
    return model and model:FindFirstChildOfClass("Humanoid") ~= nil
end

local function squaredDistance(pos1, pos2)
    local diff = pos1 - pos2
    return diff.X * diff.X + diff.Y * diff.Y + diff.Z * diff.Z
end

local function calculateAngle(direction)
    local viewVector = camera.CFrame.LookVector
    local directionUnit = direction.Unit
    local dotProduct = viewVector:Dot(directionUnit)
    local angle = math.acos(math.clamp(dotProduct, -1, 1)) * (180 / math.pi)
    return angle
end

-- Kalman Filter Implementation for Predicting Position
local function predictPosition(target)
    local hrp = target:FindFirstChild("HumanoidRootPart") or target:FindFirstChild("UpperTorso")
    local humanoidObj = target:FindFirstChildOfClass("Humanoid")

    if not hrp or not humanoidObj then
        debugLog("Target missing HumanoidRootPart or Humanoid.", "ERROR")
        return nil
    end

    -- Initialize Kalman data for the target if not already present
    if not kalmanState[target] then
        kalmanState[target] = {
            Position = hrp.Position,
            Velocity = Vector3.new(0, 0, 0),
            LastUpdate = tick()
        }
    end

    local data = kalmanState[target]
    local currentTick = tick()
    local timeElapsed = currentTick - data.LastUpdate

    if timeElapsed > 0 then
        -- Update velocity based on position difference
        local newVelocity = (hrp.Position - data.Position) / timeElapsed
        data.Velocity = newVelocity
        data.Position = hrp.Position
        data.LastUpdate = currentTick
    end

    -- Predict future position
    local predictedPos = hrp.Position + (data.Velocity * CONFIG.TRACKING.PredictionFactor)
    debugLog(string.format("Predicted Position for %s: %s", target.Name, tostring(predictedPos)), "DEBUG")
    return predictedPos
end

-- ESP Management Functions
local function createESP(target)
    local targetHead = target:FindFirstChild("Head")
    if not targetHead then
        debugLog("Cannot create ESP: Target does not have a Head.", "ERROR")
        return nil
    end

    -- Create BillboardGui
    local billboard = Instance.new("BillboardGui")
    billboard.Adornee = targetHead
    billboard.Size = CONFIG.ESP.Size
    billboard.StudsOffset = CONFIG.ESP.Offset
    billboard.AlwaysOnTop = true
    billboard.Name = "TargetESP"

    -- Create TextLabel
    local textLabel = Instance.new("TextLabel")
    textLabel.Parent = billboard
    textLabel.Size = UDim2.new(1, 0, 1, 0)
    textLabel.BackgroundTransparency = 1
    textLabel.Text = CONFIG.ESP.TextPrefix .. target.Name .. " (" .. selectedBodyPart .. ")"
    textLabel.TextColor3 = CONFIG.ESP.Color
    textLabel.Font = Enum.Font.SourceSansBold
    textLabel.TextScaled = true
    textLabel.TextStrokeTransparency = 0.8

    -- Parent to PlayerGui
    billboard.Parent = playerGui
    debugLog("ESP Indicator created for " .. target.Name, "DEBUG")

    return billboard
end

local function removeESP()
    if espIndicator then
        espIndicator:Destroy()
        espIndicator = nil
        debugLog("ESP Indicator removed.", "DEBUG")
    end
end

-- PID Controller Function
local function pidController(targetPosition, deltaTime)
    local desiredLook = (targetPosition - humanoidRootPart.Position).Unit
    local currentLook = camera.CFrame.LookVector.Unit

    -- Calculate the angle between current and desired directions
    local dotProduct = math.clamp(currentLook:Dot(desiredLook), -1, 1) -- Clamp for safety
    local angle = math.acos(dotProduct)

    -- Determine rotation direction
    local cross = currentLook:Cross(desiredLook)
    local rotationDirection = (cross.Y >= 0) and 1 or -1 -- Assuming Y-axis is up

    -- PID calculations
    local error = angle
    pidState.integral = pidState.integral + error * deltaTime
    local derivative = (error - pidState.previousError) / deltaTime

    -- PID output
    local output = (CONFIG.ROTATION.Kp * error) + (CONFIG.ROTATION.Ki * pidState.integral) + (CONFIG.ROTATION.Kd * derivative)
    output = math.clamp(output, 0, CONFIG.ROTATION.MaxTorque)

    -- Calculate the desired rotation direction
    local rotationAmount = rotationDirection * math.rad(output)

    -- Apply rotation smoothly using Lerp
    local currentCFrame = camera.CFrame
    local targetCFrame = CFrame.new(currentCFrame.Position, targetPosition)
    local smoothCFrame = currentCFrame:Lerp(targetCFrame, CONFIG.TRACKING_SMOOTHNESS.CameraLerpSpeed)
    camera.CFrame = smoothCFrame

    debugLog(string.format("Applying PID Output: %f radians", output), "DEBUG")

    -- Update previous error
    pidState.previousError = error
end

-- Direct Smooth Tracking Function
local function directSmoothTracking(targetPosition)
    if not targetPosition then return end

    -- Calculate desired CFrame
    local desiredCFrame = CFrame.new(camera.CFrame.Position, targetPosition)

    -- Smoothly interpolate the camera's CFrame
    camera.CFrame = camera.CFrame:Lerp(desiredCFrame, CONFIG.TRACKING_SMOOTHNESS.CameraLerpSpeed)

    debugLog("Directly smoothly rotated camera towards target.", "DEBUG")
end

-- Target Selection Function with FOV and Distance Prioritization
local function findBestTarget()
    local bestTarget = nil
    local shortestDistance = CONFIG.TRACKING.MaxDistance
    local bestAngle = CONFIG.TRACKING.MaxFOVAngle

    -- Iterate through all models in Workspace with Humanoid
    for _, object in ipairs(Workspace:GetDescendants()) do
        if object:IsA("Model") and hasHumanoid(object) and object ~= character then
            local targetPartName = selectedBodyPart
            local isR15 = humanoid.RigType == Enum.HumanoidRigType.R15
            local torsoPartName = isR15 and "UpperTorso" or "Torso"
            local bodyPartMappings = {
                ["Left Arm"] = isR15 and "LeftUpperArm" or "Left Arm",
                ["Left Leg"] = isR15 and "LeftUpperLeg" or "Left Leg",
                ["Torso"] = torsoPartName,
                ["Torso (Back)"] = torsoPartName,
                ["Head"] = "Head",
                ["Right Leg"] = isR15 and "RightUpperLeg" or "Right Leg",
                ["Right Arm"] = isR15 and "RightUpperArm" or "Right Arm"
            }
            local targetPart = object:FindFirstChild(bodyPartMappings[selectedBodyPart])

            if targetPart and targetPart:IsA("BasePart") then
                local direction = targetPart.Position - camera.CFrame.Position
                local distance = direction.Magnitude
                local angle = calculateAngle(direction)

                if angle <= CONFIG.TRACKING.MaxFOVAngle and distance < shortestDistance then
                    shortestDistance = distance
                    bestTarget = object
                    bestAngle = angle
                end
            end
        end
    end

    if bestTarget then
        debugLog(string.format("Best target found: %s | Distance: %.2f | Angle: %.2f", bestTarget.Name, shortestDistance, bestAngle), "INFO")
    else
        debugLog("No suitable target found within FOV and distance.", "INFO")
    end

    return bestTarget
end

-- Lock-On Toggle Function
local function toggleLockOn()
    if trackedTarget then
        -- Deselect current target
        debugLog("Deselecting target: " .. trackedTarget.Name, "INFO")
        trackedTarget = nil
        removeESP()
    else
        -- Find and select the best target
        local bestObject = findBestTarget()
        if bestObject and bestObject:IsA("Model") and hasHumanoid(bestObject) then
            trackedTarget = bestObject
            espIndicator = createESP(trackedTarget)
            debugLog("Tracking target: " .. bestObject.Name, "INFO")
        else
            debugLog("No valid target found to track.", "INFO")
        end
    end
end

-- Function: Rotate to Target (Using PID or Direct Smooth Tracking)
local function rotateToTarget(targetPosition, deltaTime)
    if shiftLockMode then
        -- Direct Smooth Tracking
        directSmoothTracking(targetPosition)
    else
        -- Smooth rotation using PID controller
        pidController(targetPosition, deltaTime)
    end
end

-- Function: Update Tracking and ESP
local function updateTracking(deltaTime)
    if not trackedTarget or not trackedTarget.Parent or not trackedTarget:FindFirstChild("HumanoidRootPart") then
        debugLog("Tracked target is invalid. Removing tracking.", "WARN")
        trackedTarget = nil
        removeESP()
        return
    end

    local targetPart = trackedTarget:FindFirstChild(selectedBodyPart == "Torso (Back)" and "UpperTorso" or selectedBodyPart)
    if not targetPart or not targetPart:IsA("BasePart") then
        debugLog("Tracked target missing the selected body part: " .. selectedBodyPart, "WARN")
        trackedTarget = nil
        removeESP()
        return
    end

    -- Predict target position using Kalman Filter
    local predictedPos = predictPosition(trackedTarget)
    if not predictedPos then
        debugLog("Failed to predict target position. Removing tracking.", "ERROR")
        trackedTarget = nil
        removeESP()
        return
    end

    -- Rotate towards predicted position
    rotateToTarget(predictedPos, deltaTime)

    -- Update ESP Adornee
    if espIndicator and trackedTarget:FindFirstChild("Head") then
        espIndicator.Adornee = trackedTarget.Head
    else
        debugLog("Target lost Head. Removing ESP.", "WARN")
        removeESP()
        trackedTarget = nil
    end
end

-- GUI Creation Function
local function createBodyPartSelectionGUI()
    -- Check if the GUI already exists to prevent duplication
    if playerGui:FindFirstChild(CONFIG.GUI.ScreenGuiName) then
        debugLog("GUI already exists. Skipping creation.", "DEBUG")
        return
    end

    -- Create ScreenGui
    local screenGui = Instance.new("ScreenGui")
    screenGui.Name = CONFIG.GUI.ScreenGuiName
    screenGui.Parent = playerGui
    screenGui.ResetOnSpawn = false

    -- Create Background Frame
    local frame = Instance.new("Frame")
    frame.Size = CONFIG.GUI.FrameSize
    frame.Position = CONFIG.GUI.FramePosition
    frame.BackgroundColor3 = CONFIG.GUI.BackgroundColor
    frame.BackgroundTransparency = 0.8
    frame.BorderSizePixel = 0
    frame.Parent = screenGui

    -- Add UIStroke for Frame
    local frameStroke = Instance.new("UIStroke")
    frameStroke.Color = CONFIG.GUI.StrokeColor
    frameStroke.Thickness = 2
    frameStroke.Parent = frame

    -- Create Title
    local title = Instance.new("TextLabel")
    title.Size = UDim2.new(1, 0, 0, 40)
    title.Position = UDim2.new(0, 0, 0, 0)
    title.BackgroundTransparency = 1
    title.Text = "Lock-On ESP"
    title.Font = Enum.Font.GothamBold
    title.TextSize = 24
    title.TextColor3 = CONFIG.GUI.TextColor
    title.TextStrokeTransparency = 0.5
    title.TextXAlignment = Enum.TextXAlignment.Center
    title.Parent = frame

    -- Create UIListLayout for organized buttons
    local uiListLayout = Instance.new("UIListLayout")
    uiListLayout.Parent = frame
    uiListLayout.FillDirection = Enum.FillDirection.Vertical
    uiListLayout.SortOrder = Enum.SortOrder.LayoutOrder
    uiListLayout.Padding = UDim.new(0, 10)
    uiListLayout.VerticalAlignment = Enum.VerticalAlignment.Top

    -- Create UIPadding to position buttons below the title
    local layoutPadding = Instance.new("UIPadding")
    layoutPadding.PaddingTop = UDim.new(0, 50)
    layoutPadding.Parent = frame

    -- Function to handle body part selection
    local function selectBodyPart(bodyPart, button)
        selectedBodyPart = bodyPart
        debugLog("Selected body part: " .. bodyPart, "INFO")
        toggleLockOn() -- Deselect current target

        -- Update ESP text if a target is already locked on
        if trackedTarget and espIndicator then
            removeESP()
            toggleLockOn() -- Re-select target with new body part
        end

        -- Update button colors to indicate selection
        for _, btn in ipairs(frame:GetChildren()) do
            if btn:IsA("TextButton") then
                btn.BackgroundColor3 = CONFIG.GUI.UnselectedColor
            end
        end
        button.BackgroundColor3 = CONFIG.GUI.SelectedColor
    end

    -- Create Buttons for each Body Part
    for _, bodyPart in ipairs(CONFIG.GUI.BodyParts) do
        local button = Instance.new("TextButton")
        button.Size = CONFIG.GUI.ButtonSize
        button.Text = bodyPart
        button.Font = Enum.Font.Gotham
        button.TextSize = 18
        button.TextColor3 = CONFIG.GUI.TextColor
        button.BackgroundColor3 = (bodyPart == selectedBodyPart) and CONFIG.GUI.SelectedColor or CONFIG.GUI.UnselectedColor
        button.AutoButtonColor = false
        button.BorderSizePixel = 0
        button.Parent = frame

        -- Add UIStroke for Buttons
        local buttonStroke = Instance.new("UIStroke")
        buttonStroke.Color = CONFIG.GUI.StrokeColor
        buttonStroke.Thickness = 1
        buttonStroke.Parent = button

        -- Hover Effects
        button.MouseEnter:Connect(function()
            if bodyPart ~= selectedBodyPart then
                button.BackgroundColor3 = CONFIG.GUI.HoverColor
            end
        end)

        button.MouseLeave:Connect(function()
            if bodyPart ~= selectedBodyPart then
                button.BackgroundColor3 = CONFIG.GUI.UnselectedColor
            end
        end)

        -- Button Click Event
        button.MouseButton1Click:Connect(function()
            selectBodyPart(bodyPart, button)
        end)
    end

    debugLog("Enhanced Body Part Selection GUI created.", "INFO")
end

-- Shift Lock Toggle Function
local function toggleShiftLock()
    if shiftLockMode then
        -- Disable ShiftLock Mode
        shiftLockMode = false
        camera.CameraType = Enum.CameraType.Custom
        debugLog("ShiftLock mode disabled.", "INFO")
    else
        if trackedTarget then
            -- Disable Lock-On before enabling ShiftLock to prevent conflicts
            toggleLockOn()
        end
        -- Enable ShiftLock Mode
        shiftLockMode = true
        camera.CameraType = Enum.CameraType.Scriptable
        debugLog("ShiftLock mode enabled.", "INFO")
    end
end

-- Event Connections
local inputConnection
local characterAddedConnection
local heartbeatConnection

-- Function: Handle Model Leaving
local function onModelRemoving(leavingModel)
    if trackedTarget and leavingModel == trackedTarget then
        debugLog("Tracked target left the game.", "WARN")
        trackedTarget = nil
        removeESP()
    end
end

-- Function: Handle Model Removal
local function onModelRemovingHandler(model)
    if model:IsA("Model") and hasHumanoid(model) then
        model.AncestryChanged:Connect(function(_, parent)
            if not parent then
                onModelRemoving(model)
            end
        end)
    end
end

-- Function: Monitor Tracked Target for Removal or Death
local function monitorTrackedTarget(target)
    if not target then return end

    local humanoid = target:FindFirstChildOfClass("Humanoid")
    if humanoid then
        humanoid.Died:Connect(function()
            debugLog("Tracked target " .. target.Name .. " has died.", "INFO")
            trackedTarget = nil
            removeESP()
        end)
    end

    target.AncestryChanged:Connect(function(_, parent)
        if not parent then
            debugLog("Tracked target " .. target.Name .. " has been removed from the game.", "WARN")
            trackedTarget = nil
            removeESP()
        end
    end)
end

-- Function: Clean Up All Connections and Resources
local function cleanup()
    if inputConnection then
        inputConnection:Disconnect()
        debugLog("Input connection disconnected.", "DEBUG")
    end
    if characterAddedConnection then
        characterAddedConnection:Disconnect()
        debugLog("CharacterAdded connection disconnected.", "DEBUG")
    end
    if heartbeatConnection then
        heartbeatConnection:Disconnect()
        debugLog("Heartbeat connection disconnected.", "DEBUG")
    end
    removeESP()
    -- Clear Kalman state
    for k in pairs(kalmanState) do
        kalmanState[k] = nil
    end
    debugLog("Cleanup complete. All connections disconnected and resources freed.", "INFO")
end

-- Initialize Function
local function initialize()
    -- Create the Body Part Selection GUI
    createBodyPartSelectionGUI()

    -- Input Listener for E key (Toggle Lock-On) and Shift key
    inputConnection = UserInputService.InputBegan:Connect(function(input, gameProcessed)
        if gameProcessed then return end
        if input.KeyCode == Enum.KeyCode.E then
            toggleLockOn()
            if trackedTarget then
                monitorTrackedTarget(trackedTarget)
            end
        elseif input.KeyCode == CONFIG.SHIFT_LOCK.ToggleKey then
            toggleShiftLock()
        end
    end)
    debugLog("Input connection established for toggleLockOn and ShiftLock.", "DEBUG")

    -- Character Respawn Listener
    characterAddedConnection = player.CharacterAdded:Connect(function(newCharacter)
        character = newCharacter
        humanoid = character:WaitForChild("Humanoid")
        humanoidRootPart = character:WaitForChild("HumanoidRootPart")
        pidState = { integral = 0, previousError = 0 }
        trackedTarget = nil
        removeESP()
        debugLog("Character respawned. Resetting tracking and ESP.", "INFO")
    end)

    -- Heartbeat Listener for Smooth Updates
    heartbeatConnection = RunService.RenderStepped:Connect(function(deltaTime)
        if trackedTarget then
            updateTracking(deltaTime)
        end
    end)
    debugLog("RenderStepped connection established for tracking updates.", "DEBUG")

    -- Connect to PlayerRemoving
    Players.PlayerRemoving:Connect(function(leavingPlayer)
        if trackedTarget and joinedPlayers[leavingPlayer] then
            debugLog("Tracked player left the game.", "WARN")
            trackedTarget = nil
            removeESP()
        end
    end)

    -- Connect to existing models' removal
    for _, obj in ipairs(Workspace:GetDescendants()) do
        if obj:IsA("Model") and hasHumanoid(obj) and obj ~= character then
            onModelRemovingHandler(obj)
        end
    end

    -- Connect to future models' removal
    Workspace.DescendantAdded:Connect(function(obj)
        if obj:IsA("Model") and hasHumanoid(obj) and obj ~= character then
            onModelRemovingHandler(obj)
        end
    end)
end

-- Cleanup on Script Removal
script.AncestryChanged:Connect(function(_, parent)
    if not parent then
        -- Script is being removed
        cleanup()
    end
end)

-- Initialize Script
initialize()
debugLog("Enhanced tracking script initialized successfully.", "INFO")