-- Rayfield UI 라이브러리 불러오기
local Rayfield = loadstring(game:HttpGet('https://[Log in to view URL]'))()

-- 서비스 및 필수 변수 설정
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")

local MAX_HEALTH = 150

local LocalPlayer = Players.LocalPlayer
local Camera = Workspace.CurrentCamera

local UserInputService = game:GetService("UserInputService")
local isLeftClickHeld = false

-- ==================== [상태 및 설정 변수] ====================
local flyEnabled = false
local noclipEnabled = false
local flySpeed = 50
local walkSpeed = 16
local bodyVelocity = nil
local bodyGyro = nil
local noclipConnection = nil

-- ==========================================
-- [1] ESP 설정 값
-- ==========================================
local ESPSettings = {
    Highlight = true,
    Skeleton  = true,
    Name      = true,
    Health    = true,
    Distance  = true,
}

local SkeletonBones = {
    {"Head", "UpperTorso"},
    {"UpperTorso", "LowerTorso"},
    {"UpperTorso", "LeftUpperArm"},
    {"LeftUpperArm", "LeftLowerArm"},
    {"UpperTorso", "RightUpperArm"},
    {"RightUpperArm", "RightLowerArm"},
    {"LowerTorso", "LeftUpperLeg"},
    {"LeftUpperLeg", "LeftLowerLeg"},
    {"LowerTorso", "RightUpperLeg"},
    {"RightUpperLeg", "RightLowerLeg"}
}

-- 전투 및 에임 설정
local aimAssistEnabled = false
local autoShotEnabled = false
local showFovCircle = true
local fovRadius = 100
local isRightClickHeld = false

local aimPartMode = "HEAD" -- "HEAD", "BODY", "RANDOM"
local currentAimPartName = "Head"
local lastRandomTime = tick()

local GameMode = "1v1 (개인전)"
local Whitelist = {}

-- 레이지 봇 설정
local RageEnabled = false
local AutoClickEnabled = false
local TargetPlayer = nil
local isAutoClicking = false

-- 무기 쿨다운 원본 백업용 테이블
local originalWeaponStats = {}

-- ==================== [FOV 원 GUI 생성] ====================
local fovScreenGui = Instance.new("ScreenGui")
fovScreenGui.Name = "FOVScreenGui"
fovScreenGui.ResetOnSpawn = false
fovScreenGui.Parent = LocalPlayer:WaitForChild("PlayerGui")

local fovFrame = Instance.new("Frame")
fovFrame.Name = "FOVFrame"
fovFrame.AnchorPoint = Vector2.new(0.5, 0.5)
fovFrame.Position = UDim2.new(0.5, 0, 0.5, 0)
fovFrame.Size = UDim2.new(0, fovRadius * 2, 0, fovRadius * 2)
fovFrame.BackgroundTransparency = 1
fovFrame.Visible = showFovCircle
fovFrame.Parent = fovScreenGui

local uiCorner = Instance.new("UICorner")
uiCorner.CornerRadius = UDim.new(1, 0)
uiCorner.Parent = fovFrame

local uiStroke = Instance.new("UIStroke")
uiStroke.Color = Color3.fromRGB(255, 255, 255)
uiStroke.Thickness = 1.5
uiStroke.Transparency = 0.3
uiStroke.Parent = fovFrame

local function updateFovSize(newRadius)
    fovRadius = newRadius
    fovFrame.Size = UDim2.new(0, fovRadius * 2, 0, fovRadius * 2)
end

-- ==================== [팀 판별 및 적 체크 로직] ====================
local function getTeamID(player)
    local teamID = player:GetAttribute("TeamID")
    if teamID then return teamID end

    if player.Character then
        local teamValue = player.Character:FindFirstChild("TeamID")
        if teamValue and (teamValue:IsA("StringValue") or teamValue:IsA("IntValue")) then
            return teamValue.Value
        end
    end

    if player.Team then
        return player.Team.Name
    end

    return nil
end

local function isEnemy(player)
    if not player or player == LocalPlayer then return false end

    if GameMode == "1v1 (개인전)" then
        return true
    else
        local myTeam = getTeamID(LocalPlayer)
        local theirTeam = getTeamID(player)

        if not myTeam or not theirTeam then
            return true
        end

        return myTeam ~= theirTeam
    end
end

-- ==================== [벽 뒤 감지 (Raycast)] ====================
local function isPartVisible(targetPart)
    if not targetPart then return false end
    local myChar = LocalPlayer.Character
    if not myChar or not myChar:FindFirstChild("Head") then return false end

    local origin = Camera.CFrame.Position
    local destination = targetPart.Position
    local direction = destination - origin

    local raycastParams = RaycastParams.new()
    raycastParams.FilterType = RaycastFilterType.Exclude
    raycastParams.FilterDescendantsInstances = {myChar, targetPart.Parent}
    raycastParams.IgnoreWater = true

    local result = Workspace:Raycast(origin, direction, raycastParams)
    return result == nil
end

-- ==================== [조준 부위 계산] ====================
local function getTargetPartName()
    if aimPartMode == "HEAD" then
        return "Head"
    elseif aimPartMode == "BODY" then
        return "HumanoidRootPart"
    elseif aimPartMode == "RANDOM" then
        if tick() - lastRandomTime >= 5 then
            lastRandomTime = tick()
            currentAimPartName = (math.random(1, 2) == 1) and "Head" or "HumanoidRootPart"
        end
        return currentAimPartName
    end
    return "Head"
end

-- ==================== [타겟 탐색 로직 (FOV 기반)] ====================
local function getTarget()
    local closestTarget = nil
    local shortestDistance = fovRadius
    local viewportCenter = Vector2.new(Camera.ViewportSize.X / 2, Camera.ViewportSize.Y / 2)
    local partName = getTargetPartName()

    for _, player in ipairs(Players:GetPlayers()) do
        if player ~= LocalPlayer and not table.find(Whitelist, player.Name) and isEnemy(player) then
            local char = player.Character
            if char then
                local humanoid = char:FindFirstChildOfClass("Humanoid")
                local targetPart = char:FindFirstChild(partName) or char:FindFirstChild("Head")

                if humanoid and humanoid.Health > 0 and targetPart then
                    if isPartVisible(targetPart) then
                        local screenPosition, onScreen = Camera:WorldToViewportPoint(targetPart.Position)

                        if onScreen then
                            local targetScreenPos = Vector2.new(screenPosition.X, screenPosition.Y)
                            local distanceToCenter = (targetScreenPos - viewportCenter).Magnitude

                            if distanceToCenter <= shortestDistance then
                                shortestDistance = distanceToCenter
                                closestTarget = {Player = player, Part = targetPart}
                            end
                        end
                    end
                end
            end
        end
    end

    return closestTarget
end

-- ==================== [타겟 탐색 로직 (거리 기반 - Rage 전용)] ====================
local function getClosestPlayer()
    local closestPlayer = nil
    local shortestDistance = math.huge

    for _, player in pairs(Players:GetPlayers()) do
        if player ~= LocalPlayer and not table.find(Whitelist, player.Name) and isEnemy(player) then
            if player.Character and player.Character:FindFirstChild("HumanoidRootPart") and player.Character:FindFirstChild("Humanoid") then
                if player.Character.Humanoid.Health > 0 and LocalPlayer.Character and LocalPlayer.Character:FindFirstChild("HumanoidRootPart") then
                    local distance = (LocalPlayer.Character.HumanoidRootPart.Position - player.Character.HumanoidRootPart.Position).Magnitude
                    if distance < shortestDistance then
                        shortestDistance = distance
                        closestPlayer = player
                    end
                end
            end
        end
    end
    return closestPlayer
end

-- ==================== [총기 쿨다운 제어 로직 (토글형)] ====================
local function toggleWeaponCooldowns(state)
    local weaponDataCache
    local modulesFolder = ReplicatedStorage:FindFirstChild("Modules")
    if modulesFolder then
        local possibleNames = {"ItemLibrary", "WeaponStats", "Items", "WeaponData", "Weapons"}
        for _, name in ipairs(possibleNames) do
            local found = modulesFolder:FindFirstChild(name)
            if found then
                weaponDataCache = require(found)
                break
            end
        end
    end

    if weaponDataCache and weaponDataCache.Items then
        local cooldownKeys = {
            "ShootCooldown", "ShootBurstCooldown", "AttackCooldown", 
            "HeavyAttackCooldown", "Cooldown", "DeflectCooldown", 
            "DashCooldown", "BuildCooldown", "SpinCooldown", 
            "AirblastCooldown", "QuickShotCooldown", "TransitionCooldown"
        }

        for itemId, stats in pairs(weaponDataCache.Items) do
            if state then
                -- 원본 값 백업
                if not originalWeaponStats[itemId] then
                    originalWeaponStats[itemId] = {}
                    for _, key in ipairs(cooldownKeys) do
                        originalWeaponStats[itemId][key] = stats[key]
                    end
                    originalWeaponStats[itemId]["ReloadTime"] = stats.ReloadTime
                end

                -- 쿨다운 제거 (음수가 아닌 0 또는 0.01로 안전 적용)
                for _, key in ipairs(cooldownKeys) do
                    if stats[key] then stats[key] = 0 end
                end
                if stats.ReloadTime then stats.ReloadTime = 0.01 end
            else
                -- 원본 값 복원
                if originalWeaponStats[itemId] then
                    for key, origVal in pairs(originalWeaponStats[itemId]) do
                        stats[key] = origVal
                    end
                end
            end
        end

        if state then
            Rayfield:Notify({Title = "총기 쿨다운", Content = "모든 무기 쿨다운이 제거되었습니다!", Duration = 2})
        else
            Rayfield:Notify({Title = "총기 쿨다운", Content = "무기 쿨다운이 원상복구되었습니다.", Duration = 2})
        end
    else
        Rayfield:Notify({Title = "총기 쿨다운", Content = "무기 데이터 모듈을 찾을 수 없습니다.", Duration = 2})
    end
end

-- ==================== [입력 이벤트] ====================
UserInputService.InputBegan:Connect(function(input, gameProcessed)
    if gameProcessed then return end
    
    if input.UserInputType == Enum.UserInputType.MouseButton2 then
        isRightClickHeld = true
    end
end)

UserInputService.InputEnded:Connect(function(input, gameProcessed)
    if input.UserInputType == Enum.UserInputType.MouseButton2 then
        isRightClickHeld = false
    end
end)
-- ==================== [메인 렌더링 루프 (에임 보정 & Rage TP)] ====================
RunService.RenderStepped:Connect(function()
    -- 1. 기본 에임 보정 (Aim Assist)
    if aimAssistEnabled then
        local targetData = getTarget()
        if targetData and targetData.Part then
            local targetPart = targetData.Part

            if isRightClickHeld then
                Camera.CFrame = CFrame.new(Camera.CFrame.Position, targetPart.Position)
            end

            if autoShotEnabled then
                mouse1click()
            end
        end
    end

    -- 2. 레이지 TP 봇 (Rage Bot)
    if RageEnabled then
        local myRoot = LocalPlayer.Character and LocalPlayer.Character:FindFirstChild("HumanoidRootPart")
        if myRoot then
            TargetPlayer = getClosestPlayer()
            if TargetPlayer and TargetPlayer.Character then
                local enemyRoot = TargetPlayer.Character:FindFirstChild("HumanoidRootPart")
                local enemyHead = TargetPlayer.Character:FindFirstChild("Head")
                local enemyHumanoid = TargetPlayer.Character:FindFirstChild("Humanoid")

                if enemyRoot and enemyHead and enemyHumanoid and enemyHumanoid.Health > 0 then
                    -- 적 뒤 위치 계산 및 순간이동
                    local backOffset = -enemyRoot.CFrame.LookVector * 3.5
                    local targetPosition = enemyRoot.Position + backOffset
                    myRoot.CFrame = CFrame.new(targetPosition, enemyHead.Position)

                    -- 카메라 조준
                    Camera.CFrame = CFrame.new(Camera.CFrame.Position, enemyHead.Position)

                    -- 오토 클릭 (비동기 루프 처리)
                    if AutoClickEnabled and not isAutoClicking then
                        isAutoClicking = true
                        task.spawn(function()
                            mouse1click()
                            isAutoClicking = false
                        end)
                    end
                end
            end
        end
    end
end)

local function getPlayerNames()
    local names = {}
    for _, p in pairs(Players:GetPlayers()) do
        if p ~= LocalPlayer then
            table.insert(names, p.Name)
        end
    end
    return names
end

-- ==================== [Rayfield UI 구성] ====================
local Window = Rayfield:CreateWindow({
    Name = "Studio Admin Controller",
    LoadingTitle = "Control Panel",
    LoadingSubtitle = "by Assistant",
    ConfigurationSaving = { Enabled = false },
    KeySystem = false
})

local MovementTab = Window:CreateTab("이동 (Movement)", 4483362458)
local CombatTab = Window:CreateTab("전투 및 에임 (Combat)", 4483362458)
local RageTab = Window:CreateTab("레이지 및 기타 (Rage & Misc)", 4483362458)
local espTab = Window:CreateTab("esp (esp)", 4483362458)

-- ---------------- [이동 탭] ----------------
MovementTab:CreateToggle({
    Name = "Fly (비행)",
    CurrentValue = false,
    Callback = function(Value)
        flyEnabled = Value
        local character = LocalPlayer.Character
        if flyEnabled and character and character:FindFirstChild("HumanoidRootPart") then
            local root = character.HumanoidRootPart
            bodyVelocity = Instance.new("BodyVelocity", root)
            bodyVelocity.MaxForce = Vector3.new(1e6, 1e6, 1e6)
            bodyVelocity.Velocity = Vector3.zero

            bodyGyro = Instance.new("BodyGyro", root)
            bodyGyro.MaxTorque = Vector3.new(1e6, 1e6, 1e6)
            bodyGyro.P = 9000
            bodyGyro.CFrame = root.CFrame

            task.spawn(function()
                while flyEnabled and character and character:FindFirstChild("Humanoid") do
                    local moveDir = Vector3.zero
                    if UserInputService:IsKeyDown(Enum.KeyCode.W) then moveDir = moveDir + Camera.CFrame.LookVector end
                    if UserInputService:IsKeyDown(Enum.KeyCode.S) then moveDir = moveDir - Camera.CFrame.LookVector end
                    if UserInputService:IsKeyDown(Enum.KeyCode.A) then moveDir = moveDir - Camera.CFrame.RightVector end
                    if UserInputService:IsKeyDown(Enum.KeyCode.D) then moveDir = moveDir + Camera.CFrame.RightVector end
                    if UserInputService:IsKeyDown(Enum.KeyCode.Space) then moveDir = moveDir + Vector3.new(0, 1, 0) end
                    if UserInputService:IsKeyDown(Enum.KeyCode.LeftShift) then moveDir = moveDir - Vector3.new(0, 1, 0) end

                    if moveDir.Magnitude > 0 then moveDir = moveDir.Unit end
                    bodyVelocity.Velocity = moveDir * flySpeed
                    bodyGyro.CFrame = Camera.CFrame
                    RunService.RenderStepped:Wait()
                end
            end)
        else
            if bodyVelocity then bodyVelocity:Destroy() bodyVelocity = nil end
            if bodyGyro then bodyGyro:Destroy() bodyGyro = nil end
        end
    end,
})

MovementTab:CreateSlider({
    Name = "Fly Speed",
    Range = {10, 300},
    Increment = 5,
    Suffix = "Speed",
    CurrentValue = 50,
    Callback = function(Value) flySpeed = Value end,
})

MovementTab:CreateToggle({
    Name = "Noclip (벽 통과)",
    CurrentValue = false,
    Callback = function(Value)
        noclipEnabled = Value
        if noclipEnabled then
            noclipConnection = RunService.Stepped:Connect(function()
                local character = LocalPlayer.Character
                if character then
                    for _, part in ipairs(character:GetDescendants()) do
                        if part:IsA("BasePart") and part.CanCollide then
                            part.CanCollide = false
                        end
                    end
                end
            end)
        else
            if noclipConnection then noclipConnection:Disconnect() noclipConnection = nil end
            local character = LocalPlayer.Character
            if character then
                for _, part in ipairs(character:GetDescendants()) do
                    if part:IsA("BasePart") and part.Name ~= "HumanoidRootPart" then
                        part.CanCollide = true
                    end
                end
            end
        end
    end,
})

MovementTab:CreateSlider({
    Name = "Walk Speed (기본 이동 속도)",
    Range = {16, 250},
    Increment = 2,
    Suffix = "Speed",
    CurrentValue = 16,
    Callback = function(Value)
        walkSpeed = Value
        if LocalPlayer.Character and LocalPlayer.Character:FindFirstChild("Humanoid") then
            LocalPlayer.Character.Humanoid.WalkSpeed = walkSpeed
        end
    end,
})

-- ---------------- [전투 및 에임 탭] ----------------
CombatTab:CreateToggle({
    Name = "aim bot",
    CurrentValue = false,
    Callback = function(Value) aimAssistEnabled = Value end,
})

CombatTab:CreateToggle({
    Name = "trigger bot",
    CurrentValue = false,
    Callback = function(Value) autoShotEnabled = Value end,
})

CombatTab:CreateDropdown({
    Name = "조준 부위 선택",
    Options = {"HEAD", "BODY", "RANDOM (5초마다 변경)"},
    CurrentOption = "HEAD",
    MultipleOptions = false,
    Callback = function(Option)
        local selected = Option[1]
        if string.find(selected, "HEAD") then
            aimPartMode = "HEAD"
        elseif string.find(selected, "BODY") then
            aimPartMode = "BODY"
        else
            aimPartMode = "RANDOM"
            lastRandomTime = tick()
        end
    end,
})

CombatTab:CreateDropdown({
    Name = "Game Mode (게임 모드 선택)",
    Options = {"1v1 (개인전)", "2v2 ~ 5v5 (팀전)"},
    CurrentOption = "1v1 (개인전)",
    MultipleOptions = false,
    Callback = function(Options)
        GameMode = Options[1]
        Rayfield:Notify({Title = "모드 변경", Content = "현재 모드: " .. GameMode, Duration = 2})
    end,
})

CombatTab:CreateSlider({
    Name = "FOV Size (범위 크기)",
    Range = {30, 400},
    Increment = 5,
    Suffix = "px",
    CurrentValue = 100,
    Callback = function(Value) updateFovSize(Value) end,
})

CombatTab:CreateToggle({
    Name = "Show FOV Circle (원 표시)",
    CurrentValue = true,
    Callback = function(Value)
        showFovCircle = Value
        fovFrame.Visible = showFovCircle
    end,
})

-- ---------------- [레이지 및 기타 탭] ----------------
RageTab:CreateToggle({
    Name = "Rage bot",
    CurrentValue = false,
    Callback = function(Value)
        RageEnabled = Value
        AutoClickEnabled = Value 
        if Value then
            Rayfield:Notify({Title = "Rage Bot", Content = "레이지 봇 및 자동 공격이 활성화되었습니다.", Duration = 2})
        else
            Rayfield:Notify({Title = "Rage Bot", Content = "레이지 봇 비활성화", Duration = 2})
        end
    end,
})

RageTab:CreateToggle({
    Name = "No Weapon Cooldown (총기 쿨다운 제거)",
    CurrentValue = false,
    Callback = function(Value)
        toggleWeaponCooldowns(Value)
    end,
})

local WhitelistDropdown = RageTab:CreateDropdown({
    Name = "Whitelist (타겟 예외 유저)",
    Options = getPlayerNames(),
    CurrentOption = {},
    MultipleOptions = true,
    Callback = function(Options) Whitelist = Options end,
})

-- ==================== [이벤트 리스너] ====================
Players.PlayerAdded:Connect(function()
    if WhitelistDropdown then WhitelistDropdown:Refresh(getPlayerNames(), true) end
end)

Players.PlayerRemoving:Connect(function()
    if WhitelistDropdown then WhitelistDropdown:Refresh(getPlayerNames(), true) end
end)

LocalPlayer.CharacterAdded:Connect(function(char)
    local humanoid = char:WaitForChild("Humanoid")
    humanoid.WalkSpeed = walkSpeed
end)

espTab:CreateDropdown({
    Name = "ESP 항목 선택",
    Options = {"형광 실루엣", "스켈레톤", "닉네임", "체력", "거리"},
    CurrentOption = {"형광 실루엣", "스켈레톤", "닉네임", "체력", "거리"}, -- 기본 선택값
    MultipleOptions = true,
    Flag = "ESP_Dropdown",
    Callback = function(Options)
        -- 모든 옵션 초기화 후 선택된 값만 true 처리
        ESPSettings.Highlight = false
        ESPSettings.Skeleton = false
        ESPSettings.Name = false
        ESPSettings.Health = false
        ESPSettings.Distance = false

        for _, selected in ipairs(Options) do
            if selected == "형광 실루엣" then ESPSettings.Highlight = true end
            if selected == "스켈레톤" then ESPSettings.Skeleton = true end
            if selected == "닉네임" then ESPSettings.Name = true end
            if selected == "체력" then ESPSettings.Health = true end
            if selected == "거리" then ESPSettings.Distance = true end
        end
    end,
})

-- ==========================================
-- [3] ESP 로직 구현
-- ==========================================
local function createSkeletonLine(character, partAName, partBName)
    local partA = character:FindFirstChild(partAName)
    local partB = character:FindFirstChild(partBName)
    if not partA or not partB then return nil end

    local line = Instance.new("LineHandleAdornment")
    line.Name = "SkeletonLine"
    line.Thickness = 3
    line.Color3 = Color3.fromRGB(0, 255, 255)
    line.AlwaysOnTop = true
    line.Adornee = partA
    line.Parent = partA

    return {Line = line, PartA = partA, PartB = partB}
end

local function applyESP(player)
    if player == LocalPlayer then return end

    local function onCharacterAdded(character)
        local humanoid = character:WaitForChild("Humanoid")
        local head = character:WaitForChild("Head")
        local root = character:WaitForChild("HumanoidRootPart")

        humanoid.MaxHealth = MAX_HEALTH

        -- 1. Highlight
        local highlight = Instance.new("Highlight")
        highlight.Name = "ESPHighlight"
        highlight.FillColor = Color3.fromRGB(255, 0, 128)
        highlight.DepthMode = Enum.HighlightDepthMode.AlwaysOnTop
        highlight.Parent = character

        -- 2. BillboardGui
        local gui = Instance.new("BillboardGui")
        gui.Name = "ESPInfo"
        gui.Size = UDim2.new(0, 220, 0, 40)
        gui.StudsOffset = Vector3.new(0, 3.5, 0)
        gui.AlwaysOnTop = true
        gui.Parent = head

        local label = Instance.new("TextLabel")
        label.Size = UDim2.new(1, 0, 1, 0)
        label.BackgroundTransparency = 1
        label.TextColor3 = Color3.fromRGB(255, 255, 0)
        label.TextStrokeTransparency = 0
        label.TextSize = 14
        label.Font = Enum.Font.GothamBold
        label.Parent = gui

        -- 3. Skeleton
        local activeLines = {}
        task.spawn(function()
            task.wait(0.5)
            for _, pair in ipairs(SkeletonBones) do
                local lineData = createSkeletonLine(character, pair[1], pair[2])
                if lineData then table.insert(activeLines, lineData) end
            end
        end)

        -- 실시간 위치/텍스트/온오프 업데이트
        local connection
        connection = RunService.RenderStepped:Connect(function()
            if not character:Parent() or humanoid.Health <= 0 then
                connection:Disconnect()
                return
            end

            highlight.Enabled = ESPSettings.Highlight

            local textParts = {}
            if ESPSettings.Name then table.insert(textParts, player.DisplayName) end
            
            if ESPSettings.Health then 
                local currentHp = math.clamp(math.floor(humanoid.Health), 0, MAX_HEALTH)
                table.insert(textParts, "[" .. currentHp .. "/" .. MAX_HEALTH .. " HP]") 
            end

            if ESPSettings.Distance and LocalPlayer.Character and LocalPlayer.Character:FindFirstChild("HumanoidRootPart") then
                local dist = math.floor((LocalPlayer.Character.HumanoidRootPart.Position - root.Position).Magnitude)
                table.insert(textParts, dist .. "m")
            end

            label.Text = table.concat(textParts, " | ")
            gui.Enabled = (#textParts > 0)

            for _, item in ipairs(activeLines) do
                if item.Line and item.PartA and item.PartB then
                    item.Line.Visible = ESPSettings.Skeleton
                    if ESPSettings.Skeleton then
                        local dir = item.PartB.Position - item.PartA.Position
                        item.Line.Length = dir.Magnitude
                        item.Line.CFrame = CFrame.lookAt(Vector3.zero, dir)
                    end
                end
            end
        end)
    end

    if player.Character then onCharacterAdded(player.Character) end
    player.CharacterAdded:Connect(onCharacterAdded)
end

for _, player in ipairs(Players:GetPlayers()) do applyESP(player) end
Players.PlayerAdded:Connect(applyESP)

Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: