Unnamed esp universal
Key RequiredUniversal

Unnamed esp universal

Universal ScriptZcel35Zcel35 2.4K views 4.4K executesUpdated Aug 2, 2026
0.0/ 5(1 votes)
010% Positive
Lua Script•1690 lines (84529 chars)
assert(Drawing, 'exploit not supported')

if not syn and not PROTOSMASHER_LOADED then print'Unnamed ESP only officially supports Synapse and Protosmasher! If you\'re an exploit developer and have added drawing API to your exploit, try setting syn as true then checking if that works, otherwise, DM me on discord @ cppbook.org#1968 or add an issue to the Unnamed ESP Github Repository and I\'ll see it through email!' end

if not cloneref then cloneref = function(o) return o end end

local UserInputService = cloneref(game:GetService('UserInputService'))
local HttpService = cloneref(game:GetService('HttpService'))
local TweenService = cloneref(game:GetService('TweenService'))
local RunService = cloneref(game:GetService('RunService'))
local Players = game:GetService('Players')
local LocalPlayer = Players.LocalPlayer
local Camera = workspace.CurrentCamera
local Mouse = LocalPlayer:GetMouse()
local V2New = Vector2.new
local V3New = Vector3.new
local WTVP = Camera.WorldToViewportPoint
local WorldToViewport = function(...) return WTVP(Camera, ...) end
local Menu = {}
local MouseHeld = false
local LastRefresh = 0
local OptionsFile = 'IC3_ESP_SETTINGS.dat'
local Binding = false
local BindedKey = nil
local OIndex = 0
local LineBox = {}
local UIButtons = {}
local Sliders = {}
local ColorPicker = { Loading = false, LastGenerated = 0 }
local Dragging = false
local DraggingUI = false
local Rainbow = false
local DragOffset = V2New()
local DraggingWhat = nil
local OldData = {}
local IgnoreList = {}
local EnemyColor = Color3.new(1, 0, 0)
local TeamColor = Color3.new(0, 1, 0)
local MenuLoaded = false
local ErrorLogging = false
local TracerPosition = V2New(Camera.ViewportSize.X / 2, Camera.ViewportSize.Y - 135)
local DragTracerPosition = false
local SubMenu = {}
local IsSynapse = syn and not PROTOSMASHER_LOADED
local Connections = { Active = {} }
local Signal = {} Signal.__index = Signal
local GetCharacter, CurrentColorPicker, Spectating

local QUAD_SUPPORTED_EXPLOIT = pcall(function() Drawing.new('Quad'):Remove() end)

shared.MenuDrawingData = shared.MenuDrawingData or { Instances = {} }
shared.InstanceData = shared.InstanceData or {}
shared.RSName = shared.RSName or ('UnnamedESP_by_ic3-' .. HttpService:GenerateGUID(false))

local GetDataName = shared.RSName .. '-GetData'
local UpdateName = shared.RSName .. '-Update'

local Debounce = setmetatable({}, {
    __index = function(t, i)
        return rawget(t, i) or false
    end
})

if shared.UESP_InputChangedCon then shared.UESP_InputChangedCon:Disconnect() end
if shared.UESP_InputBeganCon then shared.UESP_InputBeganCon:Disconnect() end
if shared.UESP_InputEndedCon then shared.UESP_InputEndedCon:Disconnect() end
if shared.CurrentColorPicker then shared.CurrentColorPicker:Dispose() end

local function IsStringEmpty(String)
    if type(String) == 'string' then
        return String:match('^%s+$') ~= nil or #String == 0 or String == '' or false
    end
    return false
end

local function Set(t, i, v) t[i] = v end

local Teams = {}
local CustomTeams = {
    [2563455047] = {
        Initialize = function()
            Teams.Sheriffs = {}; Teams.Bandits = {}
            local Func = game:GetService('ReplicatedStorage'):WaitForChild('RogueFunc', 1)
            local Event = game:GetService('ReplicatedStorage'):WaitForChild('RogueEvent', 1)
            local S, B = Func:InvokeServer('AllTeamData')
            Teams.Sheriffs = S; Teams.Bandits = B
            Event.OnClientEvent:Connect(function(id, PlayerName, Team, Remove)
                if id == 'UpdateTeam' then
                    local TeamTable, NotTeamTable
                    if Team == 'Bandits' then TeamTable = Teams.Bandits; NotTeamTable = Teams.Sheriffs
                    else TeamTable = Teams.Sheriffs; NotTeamTable = Teams.Bandits end
                    if Remove then TeamTable[PlayerName] = nil
                    else TeamTable[PlayerName] = true; NotTeamTable[PlayerName] = nil end
                    if PlayerName == LocalPlayer.Name then TDM.Friendlys = TeamTable; TDM.Enemies = NotTeamTable end
                end
            end)
        end,
        CheckTeam = function(Player)
            local LocalTeam = Teams.Sheriffs[LocalPlayer.Name] and Teams.Sheriffs or Teams.Bandits
            return LocalTeam[Player.Name] and true or false
        end
    },
    [5208655184] = {
        CheckTeam = function(Player)
            local LocalLastName = LocalPlayer:GetAttribute('LastName') if not LocalLastName or IsStringEmpty(LocalLastName) then return true end
            local PlayerLastName = Player:GetAttribute('LastName') if not PlayerLastName then return false end
            return PlayerLastName == LocalLastName
        end
    },
    [3541987450] = {
        CheckTeam = function(Player)
            local LocalStats = LocalPlayer:FindFirstChild('leaderstats')
            local LocalLastName = LocalStats and LocalStats:FindFirstChild('LastName') if not LocalLastName or IsStringEmpty(LocalLastName.Value) then return true end
            local PlayerStats = Player:FindFirstChild('leaderstats')
            local PlayerLastName = PlayerStats and PlayerStats:FindFirstChild('LastName') if not PlayerLastName then return false end
            return PlayerLastName.Value == LocalLastName.Value
        end
    },
    [6032399813] = {
        CheckTeam = function(Player)
            local LocalStats = LocalPlayer:FindFirstChild('leaderstats')
            local LocalGuildName = LocalStats and LocalStats:FindFirstChild('Guild') if not LocalGuildName or IsStringEmpty(LocalGuildName.Value) then return true end
            local PlayerStats = Player:FindFirstChild('leaderstats')
            local PlayerGuildName = PlayerStats and PlayerStats:FindFirstChild('Guild') if not PlayerGuildName then return false end
            return PlayerGuildName.Value == LocalGuildName.Value
        end
    },
    [5735553160] = {
        CheckTeam = function(Player)
            local LocalStats = LocalPlayer:FindFirstChild('leaderstats')
            local LocalGuildName = LocalStats and LocalStats:FindFirstChild('Guild') if not LocalGuildName or IsStringEmpty(LocalGuildName.Value) then return true end
            local PlayerStats = Player:FindFirstChild('leaderstats')
            local PlayerGuildName = PlayerStats and PlayerStats:FindFirstChild('Guild') if not PlayerGuildName then return false end
            return PlayerGuildName.Value == LocalGuildName.Value
        end
    }
}

local RenderList = {Instances = {}}
function RenderList:AddOrUpdateInstance(Instance, Obj2Draw, Text, Color)
    RenderList.Instances[Instance] = { ParentInstance = Instance, Instance = Obj2Draw, Text = Text, Color = Color }
    return RenderList.Instances[Instance]
end

local CustomPlayerTag; local CustomESP; local CustomCharacter
local GetHealth; local GetAliveState; local CustomRootPartName

local Modules = {
    [292439477] = {
        Initialize = function()
            if not create_comm_channel or not get_comm_channel then return end
            local run_on_actor = runonactor or run_on_actor
            local EventID, Event = create_comm_channel()
            Event.Event:Connect(function(List) PF_CharList = List end)
            for Index, Actor in pairs(getactors()) do
                run_on_actor(Actor, [[
                    local Event = get_comm_channel(...)
                    if not getrenv().shared.require then return end
                    local RunService = game:GetService('RunService')
                    local Cache = debug.getupvalues(getrenv().shared.require)[1]._cache if not Cache then return end
                    local ReplicationInterface = rawget(rawget(Cache, 'ReplicationInterface'), 'module') if not ReplicationInterface then return end
                    local getEntry = rawget(ReplicationInterface, 'getEntry')
                    if shared.UNPFHB then shared.UNPFHB:Disconnect() end
                    shared.UNPFHB = RunService.Heartbeat:Connect(function()
                        local CharacterList = {}
                        for Player, Entry in pairs(debug.getupvalues(getEntry)[1]) do
                            local TPO = rawget(Entry, '_thirdPersonObject') if not TPO then continue end
                            local Character = rawget(TPO, '_characterHash') if not Character then continue end
                            local Torso = rawget(Character, 'Torso') if not Torso then continue end
                            local HealthState = rawget(Entry, '_healthstate')
                            CharacterList[Player.Name] = {
                                Head = Character.Head, Torso = Character.Torso,
                                Health = HealthState and rawget(HealthState, 'health0') or 100,
                                Alive = rawget(Entry, '_alive')
                            }
                        end
                        Event:Fire(CharacterList)
                    end)
                ]], EventID)
            end
        end,
        CustomCharacter = function(Player)
            if not shared.PF_CharMT then
                shared.PF_CharMT = {}
                shared.PF_CharMT.__index = shared.PF_CharMT
                function shared.PF_CharMT:FindFirstChild(Name) return rawget(self, Name) end
                function shared.PF_CharMT:FindFirstChildOfClass() end
            end
            if PF_CharList and PF_CharList[Player.Name] then
                local Character = PF_CharList[Player.Name]
                setmetatable(Character, shared.PF_CharMT)
                return Character
            end
        end,
        GetHealth = function(Player) if PF_CharList and PF_CharList[Player.Name] then return PF_CharList[Player.Name].Health end end,
        GetAliveState = function(Player) if PF_CharList and PF_CharList[Player.Name] then return PF_CharList[Player.Name].Alive end end,
        CustomRootPartName = 'Torso'
    },
    [2950983942] = { CustomCharacter = function(Player) if workspace:FindFirstChild('Players') then return workspace.Players:FindFirstChild(Player.Name) end end },
    [2262441883] = {
        CustomPlayerTag = function(Player) return Player:FindFirstChild('Job') and (' [' .. Player.Job.Value .. ']') or '' end,
        CustomESP = function()
            if workspace:FindFirstChild('MoneyPrinters') then
                for i, v in pairs(workspace.MoneyPrinters:GetChildren()) do
                    local Main = v:FindFirstChild('Main'); local Owner = v:FindFirstChild('TrueOwner'); local Money = v:FindFirstChild('Int') and v.Int:FindFirstChild('Money') or nil
                    if Main and Owner and Money then
                        local O = tostring(Owner.Value); local M = tostring(Money.Value)
                        pcall(RenderList.AddOrUpdateInstance, RenderList, v, Main, string.format('Money Printer\nOwned by %s\n[%s]', O, M), Color3.fromRGB(13, 255, 227))
                    end
                end
            end
        end
    },
    [4801598506] = {
        CustomESP = function()
            if workspace:FindFirstChild('Mobs') and workspace.Mobs:FindFirstChild('Forest1') then
                for i, v in pairs(workspace.Mobs.Forest1:GetChildren()) do
                    local Main = v:FindFirstChild('Head'); local Hum = v:FindFirstChild('Mob')
                    if Main and Hum then pcall(RenderList.AddOrUpdateInstance, RenderList, v, Main, string.format('[%s] [%s/%s]', v.Name, Hum.Health, Hum.MaxHealth), Color3.fromRGB(13, 255, 227)) end
                end
            end
        end
    },
    [2555873122] = {
        CustomESP = function()
            if workspace:FindFirstChild('WoodPlanks') then
                for i, v in pairs(workspace:GetChildren()) do
                    if v.Name == 'WoodPlanks' then local Main = v:FindFirstChild('Wood')
                        if Main then pcall(RenderList.AddOrUpdateInstance, RenderList, v, Main, 'Wood Planks', Color3.fromRGB(13, 255, 227)) end
                    end
                end
            end
        end
    },
    [5208655184] = {
        CustomESP = function() end,
        CustomPlayerTag = function(Player)
            if game.PlaceVersion < 457 then return '' end
            local Name = ''; local FirstName = Player:GetAttribute('FirstName')
            if typeof(FirstName) == 'string' and #FirstName > 0 then
                local Prefix = ''; local Extra = {}; Name = Name .. '\n['
                if Player:GetAttribute('Prestige') > 0 then Name = Name .. '#' .. tostring(Player:GetAttribute('Prestige')) .. ' ' end
                if not IsStringEmpty(Player:GetAttribute('HouseRank')) then Prefix = Player:GetAttribute('HouseRank') == 'Owner' and (Player:GetAttribute('Gender') == 'Female' and 'Lady ' or 'Lord ') or '' end
                if not IsStringEmpty(FirstName) then Name = Name .. '' .. Prefix .. FirstName end
                if not IsStringEmpty(Player:GetAttribute('LastName')) then Name = Name .. ' ' .. Player:GetAttribute('LastName') end
                if not IsStringEmpty(Name) then Name = Name .. ']' end
                local Character = GetCharacter(Player)
                if Character then
                    if Character and Character:FindFirstChild('Danger') then table.insert(Extra, 'D') end
                    if Character:FindFirstChild('ManaAbilities') and Character.ManaAbilities:FindFirstChild('ManaSprint') then table.insert(Extra, 'D1') end
                    if Character:FindFirstChild('Mana') then table.insert(Extra, 'M' .. math.floor(Character.Mana.Value)) end
                    if Character:FindFirstChild('Vampirism') then table.insert(Extra, 'V') end
                    if Character:FindFirstChild('Observe') then table.insert(Extra, 'ILL') end
                    if Character:FindFirstChild('Inferi') then table.insert(Extra, 'NEC') end
                    if Character:FindFirstChild("World's Pulse") then table.insert(Extra, 'DZIN') end
                    if Character:FindFirstChild('Shift') then table.insert(Extra, 'MAD') end
                    if Character:FindFirstChild('Head') and Character.Head:FindFirstChild('FacialMarking') then
                        local FM = Character.Head:FindFirstChild('FacialMarking')
                        if FM.Texture == 'http://www.roblox.com/asset/?id=4072968006' then table.insert(Extra, 'HEALER')
                        elseif FM.Texture == 'http://www.roblox.com/asset/?id=4072914434' then table.insert(Extra, 'SEER')
                        elseif FM.Texture == 'http://www.roblox.com/asset/?id=4094417635' then table.insert(Extra, 'JESTER')
                        elseif FM.Texture == 'http://www.roblox.com/asset/?id=4072968656' then table.insert(Extra, 'BLADE') end
                    end
                end
                if Player:FindFirstChild('Backpack') then
                    if Player.Backpack:FindFirstChild('Observe') then table.insert(Extra, 'ILL') end
                    if Player.Backpack:FindFirstChild('Inferi') then table.insert(Extra, 'NEC') end
                    if Player.Backpack:FindFirstChild("World's Pulse") then table.insert(Extra, 'DZIN') end
                    if Player.Backpack:FindFirstChild('Shift') then table.insert(Extra, 'MAD') end
                end
                if #Extra > 0 then Name = Name .. ' [' .. table.concat(Extra, '-') .. ']' end
            end
            return Name
        end
    },
    [3541987450] = {
        CustomPlayerTag = function(Player)
            local Name = ''
            if Player:FindFirstChild('leaderstats') then
                Name = Name .. '\n['; local Prefix = ''; local Extra = {}
                if Player.leaderstats:FindFirstChild('Prestige') and Player.leaderstats.Prestige.ClassName == 'IntValue' and Player.leaderstats.Prestige.Value > 0 then Name = Name .. '#' .. tostring(Player.leaderstats.Prestige.Value) .. ' ' end
                if Player.leaderstats:FindFirstChild('HouseRank') and Player.leaderstats:FindFirstChild('Gender') and Player.leaderstats.HouseRank.ClassName == 'StringValue' and not IsStringEmpty(Player.leaderstats.HouseRank.Value) then Prefix = Player.leaderstats.HouseRank.Value == 'Owner' and (Player.leaderstats.Gender.Value == 'Female' and 'Lady ' or 'Lord ') or '' end
                if Player.leaderstats:FindFirstChild('FirstName') and Player.leaderstats.FirstName.ClassName == 'StringValue' and not IsStringEmpty(Player.leaderstats.FirstName.Value) then Name = Name .. '' .. Prefix .. Player.leaderstats.FirstName.Value end
                if Player.leaderstats:FindFirstChild('LastName') and Player.leaderstats.LastName.ClassName == 'StringValue' and not IsStringEmpty(Player.leaderstats.LastName.Value) then Name = Name .. ' ' .. Player.leaderstats.LastName.Value end
                if Player.leaderstats:FindFirstChild('UberTitle') and Player.leaderstats.UberTitle.ClassName == 'StringValue' and not IsStringEmpty(Player.leaderstats.UberTitle.Value) then Name = Name .. ', ' .. Player.leaderstats.UberTitle.Value end
                if not IsStringEmpty(Name) then Name = Name .. ']' end
                local Character = GetCharacter(Player)
                if Character then
                    if Character and Character:FindFirstChild('Danger') then table.insert(Extra, 'D') end
                    if Character:FindFirstChild('ManaAbilities') and Character.ManaAbilities:FindFirstChild('ManaSprint') then table.insert(Extra, 'D1') end
                    if Character:FindFirstChild('Mana') then table.insert(Extra, 'M' .. math.floor(Character.Mana.Value)) end
                    if Character:FindFirstChild('Vampirism') then table.insert(Extra, 'V') end
                    if Character:FindFirstChild('Observe') then table.insert(Extra, 'ILL') end
                    if Character:FindFirstChild('Inferi') then table.insert(Extra, 'NEC') end
                    if Character:FindFirstChild("World's Pulse") then table.insert(Extra, 'DZIN') end
                    if Character:FindFirstChild('Head') and Character.Head:FindFirstChild('FacialMarking') then
                        local FM = Character.Head:FindFirstChild('FacialMarking')
                        if FM.Texture == 'http://www.roblox.com/asset/?id=4072968006' then table.insert(Extra, 'HEALER')
                        elseif FM.Texture == 'http://www.roblox.com/asset/?id=4072914434' then table.insert(Extra, 'SEER')
                        elseif FM.Texture == 'http://www.roblox.com/asset/?id=4094417635' then table.insert(Extra, 'JESTER') end
                    end
                end
                if Player:FindFirstChild('Backpack') then
                    if Player.Backpack:FindFirstChild('Observe') then table.insert(Extra, 'ILL') end
                    if Player.Backpack:FindFirstChild('Inferi') then table.insert(Extra, 'NEC') end
                    if Player.Backpack:FindFirstChild("World's Pulse") then table.insert(Extra, 'DZIN') end
                end
                if #Extra > 0 then Name = Name .. ' [' .. table.concat(Extra, '-') .. ']' end
            end
            return Name
        end
    },
    [4691401390] = { CustomCharacter = function(Player) if workspace:FindFirstChild('Players') then return workspace.Players:FindFirstChild(Player.Name) end end },
    [6032399813] = {
        CustomPlayerTag = function(Player)
            local Name = ''; CharacterName = Player:GetAttribute('CharacterName')
            if not IsStringEmpty(CharacterName) then
                Name = ('\n[%s]'):format(CharacterName); local Character = GetCharacter(Player); local Extra = {}
                if Character then
                    local Blood, Armor = Character:FindFirstChild('Blood'), Character:FindFirstChild('Armor')
                    if Blood and Blood.ClassName == 'DoubleConstrainedValue' then table.insert(Extra, ('B%d'):format(Blood.Value)) end
                    if Armor and Armor.ClassName == 'DoubleConstrainedValue' then table.insert(Extra, ('A%d'):format(math.floor(Armor.Value / 10))) end
                end
                local BackpackChildren = Player.Backpack:GetChildren()
                for index = 1, #BackpackChildren do
                    local Oath = BackpackChildren[index]
                    if Oath.ClassName == 'Folder' and Oath.Name:find('Talent:Oath') then
                        local OathName = Oath.Name:gsub('Talent:Oath: ', '')
                        table.insert(Extra, OathName)
                    end
                end
                if #Extra > 0 then Name = Name .. ' [' .. table.concat(Extra, '-') .. ']' end
            end
            return Name
        end
    },
    [5735553160] = {
        CustomPlayerTag = function(Player)
            local Name = ''; CharacterName = Player:GetAttribute('CharacterName')
            if not IsStringEmpty(CharacterName) then
                Name = ('\n[%s]'):format(CharacterName); local Character = GetCharacter(Player); local Extra = {}
                if Character then
                    local Blood, Armor = Character:FindFirstChild('Blood'), Character:FindFirstChild('Armor')
                    if Blood and Blood.ClassName == 'DoubleConstrainedValue' then table.insert(Extra, ('B%d'):format(Blood.Value)) end
                    if Armor and Armor.ClassName == 'DoubleConstrainedValue' then table.insert(Extra, ('A%d'):format(math.floor(Armor.Value / 10))) end
                end
                local BackpackChildren = Player.Backpack:GetChildren()
                for index = 1, #BackpackChildren do
                    local Oath = BackpackChildren[index]
                    if Oath.ClassName == 'Folder' and Oath.Name:find('Talent:Oath') then
                        local OathName = Oath.Name:gsub('Talent:Oath: ', '')
                        table.insert(Extra, OathName)
                    end
                end
                if #Extra > 0 then Name = Name .. ' [' .. table.concat(Extra, '-') .. ']' end
            end
            return Name
        end
    },
    [3127094264] = {
        CustomCharacter = function(Player)
            if not _FIRST then
                _FIRST = true
                pcall(function()
                    local GPM = rawget(require(LocalPlayer.PlayerScripts:WaitForChild('Client', 1e9):WaitForChild('Player', 1e9)), 'GetPlayerModel')
                    PList = debug.getupvalue(GPM, 1)
                end)
            end
            if PList then local Player = rawget(PList, Player.UserId) if Player and Player.model then return Player.model end end
        end
    }
}

if Modules[game.PlaceId] ~= nil or Modules[game.GameId] ~= nil then
    local Module = Modules[game.PlaceId] or Modules[game.GameId]
    if Module.Initialize then Module.Initialize() end
    CustomPlayerTag = Module.CustomPlayerTag or nil
    CustomESP = Module.CustomESP or nil
    CustomCharacter = Module.CustomCharacter or nil
    GetHealth = Module.GetHealth or nil
    GetAliveState = Module.GetAliveState or nil
    CustomRootPartName = Module.CustomRootPartName or nil
end

function GetCharacter(Player)
    return CustomCharacter and CustomCharacter(Player) or Player.Character
end

function GetMouseLocation()
    return UserInputService:GetMouseLocation()
end

function MouseHoveringOver(Values)
    local X1, Y1, X2, Y2 = Values[1], Values[2], Values[3], Values[4]
    local MLocation = GetMouseLocation()
    return (MLocation.x >= X1 and MLocation.x <= (X1 + (X2 - X1))) and (MLocation.y >= Y1 and MLocation.y <= (Y1 + (Y2 - Y1)))
end

function GetTableData(t)
    if typeof(t) ~= 'table' then return end
    return setmetatable(t, {
        __call = function(t, func)
            if typeof(func) ~= 'function' then return end
            for i, v in pairs(t) do pcall(func, i, v) end
        end
    })
end

local function Format(format, ...) return string.format(format, ...) end

function CalculateValue(Min, Max, Percent)
    return Min + math.floor(((Max - Min) * Percent) + 0.5)
end

function NewDrawing(InstanceName)
    local Instance = Drawing.new(InstanceName)
    return (function(Properties)
        for i, v in pairs(Properties) do pcall(Set, Instance, i, v) end
        return Instance
    end)
end

function Menu:AddMenuInstance(Name, DrawingType, Properties)
    local Instance
    if shared.MenuDrawingData.Instances[Name] ~= nil then
        Instance = shared.MenuDrawingData.Instances[Name]
        for i, v in pairs(Properties) do pcall(Set, Instance, i, v) end
    else
        Instance = NewDrawing(DrawingType)(Properties)
    end
    shared.MenuDrawingData.Instances[Name] = Instance
    return Instance
end

function Menu:UpdateMenuInstance(Name)
    local Instance = shared.MenuDrawingData.Instances[Name]
    if Instance ~= nil then
        return (function(Properties)
            for i, v in pairs(Properties) do pcall(Set, Instance, i, v) end
            return Instance
        end)
    end
end

function Menu:GetInstance(Name)
    return shared.MenuDrawingData.Instances[Name]
end

local Options = setmetatable({}, {
    __call = function(t, ...)
        local Arguments = {...}; local Name = Arguments[1]; OIndex = OIndex + 1
        rawset(t, Name, setmetatable({
            Name = Arguments[1], Text = Arguments[2], Value = Arguments[3], DefaultValue = Arguments[3], AllArgs = Arguments, Index = OIndex
        }, {
            __call = function(t, v, force)
                local self = t
                if typeof(t.Value) == 'function' then t.Value()
                elseif typeof(t.Value) == 'EnumItem' then
                    local BT = Menu:GetInstance(Format('%s_BindText', t.Name))
                    if not force then
                        Binding = true; local Val = 0
                        while Binding do task.wait(); Val = (Val + 1) % 17; BT.Text = Val <= 8 and '|' or '' end
                    end
                    t.Value = force and v or BindedKey
                    if BT and t.BasePosition and t.BaseSize then
                        BT.Text = tostring(t.Value):match('%w+%.%w+%.(.+)')
                        BT.Position = t.BasePosition + V2New(t.BaseSize.X - BT.TextBounds.X - 20, -10)
                    end
                else
                    local NewValue = v; if NewValue == nil then NewValue = not t.Value end
                    rawset(t, 'Value', NewValue)
                    if Arguments[2] ~= nil and Menu:GetInstance('TopBar').Visible then
                        if typeof(Arguments[3]) == 'number' then
                            local AMT = Menu:GetInstance(Format('%s_AmountText', t.Name)); if AMT then AMT.Text = tostring(t.Value) end
                        else
                            local Inner = Menu:GetInstance(Format('%s_InnerCircle', t.Name)); if Inner then Inner.Visible = t.Value end
                        end
                    end
                end
            end
        }))
    end
})

function Load()
    local _, Result = pcall(readfile, OptionsFile)
    if _ then
        local _, Table = pcall(HttpService.JSONDecode, HttpService, Result)
        if _ and typeof(Table) == 'table' then
            for i, v in pairs(Table) do
                if typeof(Options[i]) == 'table' and Options[i].Value ~= nil and (typeof(Options[i].Value) == 'boolean' or typeof(Options[i].Value) == 'number') then
                    Options[i].Value = v.Value; pcall(Options[i], v.Value)
                end
            end
            if Table.TeamColor then TeamColor = Color3.new(Table.TeamColor.R, Table.TeamColor.G, Table.TeamColor.B) end
            if Table.EnemyColor then EnemyColor = Color3.new(Table.EnemyColor.R, Table.EnemyColor.G, Table.EnemyColor.B) end
            if typeof(Table.MenuKey) == 'string' then Options.MenuKey(Enum.KeyCode[Table.MenuKey], true) end
            if typeof(Table.ToggleKey) == 'string' then Options.ToggleKey(Enum.KeyCode[Table.ToggleKey], true) end
        end
    end
end

Options('Enabled', 'ESP Enabled', true)
Options('ShowTeam', 'Show Team', true)
Options('ShowTeamColor', 'Show Team Color', false)
Options('ShowName', 'Show Names', true)
Options('ShowDistance', 'Show Distance', true)
Options('ShowHealth', 'Show Health', true)
Options('ShowBoxes', 'Show Boxes', true)
Options('ShowTracers', 'Show Tracers', true)
Options('ShowDot', 'Show Head Dot', false)
Options('VisCheck', 'Visibility Check', false)
Options('Crosshair', 'Crosshair', false)
Options('TextOutline', 'Text Outline', true)
Options('TextSize', 'Text Size', syn and 18 or 14, 10, 24)
Options('MaxDistance', 'Max Distance', 2500, 100, 25000)
Options('RefreshRate', 'Refresh Rate (ms)', 5, 1, 200)
Options('YOffset', 'Y Offset', 0, -200, 200)
Options('MenuKey', 'Menu Key', Enum.KeyCode.F4, 1)
Options('ToggleKey', 'Toggle Key', Enum.KeyCode.F3, 1)
Options('ChangeColors', SENTINEL_LOADED and 'Sentinel Unsupported' or 'Change Colors', function()
    if SENTINEL_LOADED then return end
    SubMenu:Show(GetMouseLocation(), 'Unnamed Colors', {
        { Type = 'Color', Text = 'Team Color', Color = TeamColor,
            Function = function(Circ, Position)
                if tick() - ColorPicker.LastGenerated < 1 then return end
                if shared.CurrentColorPicker then shared.CurrentColorPicker:Dispose() end
                local CP = ColorPicker.new(Position - V2New(-10, 50)); CurrentColorPicker = CP; shared.CurrentColorPicker = CP
                CP.ColorChanged:Connect(function(Color) Circ.Color = Color TeamColor = Color Options.TeamColor = Color end)
            end
        },
        { Type = 'Color', Text = 'Enemy Color', Color = EnemyColor,
            Function = function(Circ, Position)
                if tick() - ColorPicker.LastGenerated < 1 then return end
                if shared.CurrentColorPicker then shared.CurrentColorPicker:Dispose() end
                local CP = ColorPicker.new(Position - V2New(-10, 50)); CurrentColorPicker = CP; shared.CurrentColorPicker = CP
                CP.ColorChanged:Connect(function(Color) Circ.Color = Color EnemyColor = Color Options.EnemyColor = Color end)
            end
        },
        { Type = 'Button', Text = 'Reset Colors', Function = function()
            EnemyColor = Color3.new(1, 0, 0); TeamColor = Color3.new(0, 1, 0)
            local C1 = Menu:GetInstance('Sub-ColorPreview.1'); if C1 then C1.Color = TeamColor end
            local C2 = Menu:GetInstance('Sub-ColorPreview.2'); if C2 then C2.Color = EnemyColor end
        end },
        { Type = 'Button', Text = 'Rainbow Mode', Function = function() Rainbow = not Rainbow end }
    })
end, 2)
Options('ResetSettings', 'Reset Settings', function()
    for i, v in pairs(Options) do
        if Options[i] ~= nil and Options[i].Value ~= nil and Options[i].Text ~= nil and (typeof(Options[i].Value) == 'boolean' or typeof(Options[i].Value) == 'number' or typeof(Options[i].Value) == 'EnumItem') then
            Options[i](Options[i].DefaultValue, true)
        end
    end
end, 5)
Options('LoadSettings', 'Load Settings', Load, 4)
Options('SaveSettings', 'Save Settings', function()
end, 3)

Load(1)
Options('MenuOpen', nil, true)

local function Combine(...)
    local Output = {}
    for i, v in pairs{...} do
        if typeof(v) == 'table' then table.foreach(v, function(i, v) Output[i] = v end) end
    end
    return Output
end

local Colors = {
    White = Color3.fromHex('ffffff'),
    Primary = { Main = Color3.fromHex('424242'), Light = Color3.fromHex('6d6d6d'), Dark = Color3.fromHex('1b1b1b') },
    Secondary = { Main = Color3.fromHex('e0e0e0'), Light = Color3.fromHex('ffffff'), Dark = Color3.fromHex('aeaeae') }
}

function Connections:Listen(Connection, Function)
    local NewConnection = Connection:Connect(Function)
    table.insert(self.Active, NewConnection)
    return NewConnection
end
function Connections:DisconnectAll()
    for Index, Connection in pairs(self.Active) do
        if Connection.Connected then Connection:Disconnect() end
    end
    self.Active = {}
end
function Signal.new()
    local self = setmetatable({ _BindableEvent = Instance.new('BindableEvent') }, Signal)
    return self
end

function Signal:Connect(Callback)
    assert(typeof(Callback) == 'function', 'function expected; got ' .. typeof(Callback))
    return self._BindableEvent.Event:Connect(function(...) Callback(...) end)
end

function Signal:Fire(...) self._BindableEvent:Fire(...) end
function Signal:Wait() return self._BindableEvent:Wait() end
function Signal:Disconnect() if self._BindableEvent then self._BindableEvent:Destroy() end end

local function IsMouseOverDrawing(Drawing, MousePosition)
    local TopLeft = Drawing.Position; local BottomRight = Drawing.Position + Drawing.Size
    local MousePosition = MousePosition or GetMouseLocation()
    return MousePosition.X > TopLeft.X and MousePosition.Y > TopLeft.Y and MousePosition.X < BottomRight.X and MousePosition.Y < BottomRight.Y
end

local ImageCache = {}
local function SetImage(Drawing, Url)
    local Data = IsSynapse and game:HttpGet(Url) or Url
    Drawing[IsSynapse and 'Data' or 'Uri'] = ImageCache[Url] or Data
    ImageCache[Url] = Data
    if not IsSynapse then repeat task.wait() until Drawing.Loaded end
end

local function CreateDrawingsTable()
    local Drawings = { __Objects = {} }; local Metatable = {}
    function Metatable.__index(self, Index)
        local Object = rawget(self.__Objects, Index)
        if not Object or (IsSynapse and not Object.__SELF.__OBJECT_EXISTS) then
            local Type = Index:sub(1, Index:find('%-') - 1)
            Success, Object = pcall(Drawing.new, Type)
            if not Object or not Success then return function() end end
            self.__Objects[Index] = setmetatable({ __SELF = Object, Type = Type }, {
                __call = function(self, Properties)
                    local Object = rawget(self, '__SELF'); if IsSynapse and not Object.__OBJECT_EXISTS then return false, 'render object destroyed' end
                    if Properties == false then Object.Visible = false; Object.Transparency = 0; Object:Remove(); return true end
                    if typeof(Properties) == 'table' then
                        for Property, Value in pairs(Properties) do
                            local CanSet = true
                            if self.Type == 'Image' and not IsSynapse and Property == 'Size' and typeof(Value) == 'Vector2' then
                                CanSet = false
                                spawn(function()
                                    repeat task.wait() until Object.Loaded
                                    if not self.DefaultSize then rawset(self, 'DefaultSize', Object.Size) end
                                    Property = 'ScaleFactor'; Value = Value.X / self.DefaultSize.X; Object[Property] = Value
                                end)
                            end
                            if CanSet then Object[Property] = Value end
                        end
                    end
                    return Object
                end
            })
            Object.Visible = true; Object.Transparency = 1
            if Type == 'Text' then
                if Drawing.Fonts then Object.Font = Drawing.Fonts.Monospace end
                Object.Size = 20; Object.Color = Color3.new(1, 1, 1); Object.Center = true
                Object.Outline = true; OutlineOpacity = 0.5
            elseif Type == 'Square' or Type == 'Rectangle' then Object.Thickness = 2; Object.Filled = false end
            return self.__Objects[Index]
        end
        return Object
    end
    function Metatable.__call(self, Delete, ...)
        if Delete == false then for Index, Drawing in pairs(rawget(self, '__Objects')) do Drawing(false) end end
    end
    return setmetatable(Drawings, Metatable)
end

local Images = {}
spawn(function()
    Images.Ring = 'https://i.imgur.com/q4qx26f.png'
    Images.Overlay = 'https://i.imgur.com/gOCxbsR.png'
end)

function ColorPicker.new(Position, Size, Color)
    ColorPicker.LastGenerated = tick(); ColorPicker.Loading = true
    local self = { Color = Color or Color3.new(1, 1, 1), HSV = { H = 0, S = 1, V = 1 } }
    local Drawings = CreateDrawingsTable()
    local Position = Position or V2New(); local Size = Size or 150
    local Padding = { 10, 10, 10, 10 }
    self.ColorChanged = Signal.new()
    Drawings['Square-Background'] { Color = Color3.fromRGB(33, 33, 33), Filled = false, Visible = false, Position = Position - V2New(Padding[4], Padding[1]), Size = V2New(Size, Size) + V2New(Padding[4] + Padding[2], Padding[1] + Padding[3]) }
    Drawings['Circle-Preview'] { Position = Position + (V2New(Size, Size) / 2), Radius = Size / 2 - 8, Filled = true, Thickness = 0, NumSides = 20, Color = Color3.new(1, 0, 0) }
    local Main = Drawings['Image-Main'] { Position = Position, Size = V2New(Size, Size) }; SetImage(Main, Images.Ring)
    local Preview = Drawings['Square-Preview'] { Position = Main.Position + (Main.Size / 4.5), Size = Main.Size / 1.75, Color = Color3.new(1, 0, 0), Filled = true, Thickness = 0 }
    local Overlay = Drawings['Image-Overlay'] { Position = Preview.Position, Size = Preview.Size, Transparency = 1 }; SetImage(Overlay, Images.Overlay)
    local CursorOutline = Drawings['Circle-CursorOutline'] { Radius = 4, Thickness = 2, Filled = false, Color = Color3.new(0.2, 0.2, 0.2), Position = V2New(Main.Position.X + Main.Size.X - 10, Main.Position.Y + (Main.Size.Y / 2)) }
    Drawings['Circle-Cursor'] { Radius = 3, Transparency = 1, Filled = true, Color = Color3.new(1, 1, 1), Position = CursorOutline.Position }
    local CursorOutlineSquare = Drawings['Circle-CursorOutlineSquare'] { Radius = 4, Thickness = 2, Filled = false, Color = Color3.new(0.2, 0.2, 0.2), Position = V2New(Preview.Position.X + Preview.Size.X - 2, Preview.Position.Y + 2) }
    Drawings['Circle-CursorSquare'] { Radius = 3, Transparency = 1, Filled = true, Color = Color3.new(1, 1, 1), Position = CursorOutlineSquare.Position }
    
    function self:UpdatePosition(Input)
        local MousePosition = V2New(Input.Position.X, Input.Position.Y + 33)
        if self.MouseHeld then
            if self.Item == 'Ring' then
                local Main = self.Drawings['Image-Main'] (); local Preview = self.Drawings['Square-Preview'] ()
                local Bounds = Main.Size / 2; local Center = Main.Position + Bounds
                local Relative = MousePosition - Center; local Direction = Relative.unit
                local Position = Center + Direction * Main.Size.X / 2.15
                local H = (math.atan2(Position.Y - Center.Y, Position.X - Center.X)) * 60
                if H < 0 then H = 360 + H end
                H = H / 360; self.HSV.H = H
                local EndColor = Color3.fromHSV(H, self.HSV.S, self.HSV.V); if EndColor ~= self.Color then self.ColorChanged:Fire(self.Color) end
                self.Drawings['Circle-Cursor'] { Position = Position }
                self.Drawings['Circle-CursorOutline'] { Position = Position }
                Preview.Color = Color3.fromHSV(H, 1, 1); self.Color = EndColor
                self.Drawings['Circle-Preview'] { Color = EndColor }
            elseif self.Item == 'HL' then
                local Preview = self.Drawings['Square-Preview'] (); local HSV = self.HSV
                local Position = V2New(math.clamp(MousePosition.X, Preview.Position.X, Preview.Position.X + Preview.Size.X), math.clamp(MousePosition.Y, Preview.Position.Y, Preview.Position.Y + Preview.Size.Y))
                HSV.S = (Position.X - Preview.Position.X) / Preview.Size.X
                HSV.V = 1 - (Position.Y - Preview.Position.Y) / Preview.Size.Y
                local EndColor = Color3.fromHSV(HSV.H, HSV.S, HSV.V); if EndColor ~= self.Color then self.ColorChanged:Fire(self.Color) end
                self.Color = EndColor
                self.Drawings['Circle-Preview'] { Color = EndColor }
                self.Drawings['Circle-CursorSquare'] { Position = Position }
                self.Drawings['Circle-CursorOutlineSquare'] { Position = Position }
            end
        end
    end
    
    function self:HandleInput(Input, P, Type)
        if Type == 'Began' then
            if Input.UserInputType.Name == 'MouseButton1' then
                local Main = self.Drawings['Image-Main'] (); local SquareSV = self.Drawings['Square-Preview'] ()
                local MousePosition = V2New(Input.Position.X, Input.Position.Y + 33)
                self.MouseHeld = true; local Bounds = Main.Size / 2; local Center = Main.Position + Bounds
                local R = (MousePosition - Center)
                if R.Magnitude < Bounds.X and R.Magnitude > Bounds.X - 20 then self.Item = 'Ring' end
                if MousePosition.X > SquareSV.Position.X and MousePosition.Y > SquareSV.Position.Y and MousePosition.X < SquareSV.Position.X + SquareSV.Size.X and MousePosition.Y < SquareSV.Position.Y + SquareSV.Size.Y then self.Item = 'HL' end
                self:UpdatePosition(Input, P)
            end
        elseif Type == 'Changed' then
            if Input.UserInputType.Name == 'MouseMovement' then self:UpdatePosition(Input, P) end
        elseif Type == 'Ended' and Input.UserInputType.Name == 'MouseButton1' then self.Item = nil end
    end
    
    function self:Dispose()
        self.Drawings(false); self.UpdatePosition = nil; self.HandleInput = nil
        Connections:DisconnectAll()
    end
    
    Connections:Listen(UserInputService.InputBegan, function(Input, Process) self:HandleInput(Input, Process, 'Began') end)
    Connections:Listen(UserInputService.InputChanged, function(Input, Process)
        if Input.UserInputType.Name == 'MouseMovement' then
            local MousePosition = V2New(Input.Position.X, Input.Position.Y + 33)
            self.Drawings['Triangle-Cursor'] { Filled = true, Color = Color3.new(0.9, 0.9, 0.9), PointA = MousePosition + V2New(0, 0), PointB = MousePosition + V2New(12, 14), PointC = MousePosition + V2New(0, 18), Thickness = 0 }
        end
        self:HandleInput(Input, Process, 'Changed')
    end)
    Connections:Listen(UserInputService.InputEnded, function(Input, Process)
        self:HandleInput(Input, Process, 'Ended')
        if Input.UserInputType.Name == 'MouseButton1' then self.MouseHeld = false end
    end)
    ColorPicker.Loading = false; self.Drawings = Drawings; return self
end

function SubMenu:Show(Position, Title, Options)
    self.Open = true; local Visible = true
    local BasePosition = Position; local BaseSize = V2New(200, 140)
    local End = BasePosition + BaseSize
    self.Bounds = { BasePosition.X, BasePosition.Y, End.X, End.Y }
    delay(0.025, function()
        if not self.Open then return end
        Menu:AddMenuInstance('Sub-Main', 'Square', { Size = BaseSize, Position = BasePosition, Filled = false, Color = Colors.Primary.Main, Thickness = 3, Visible = Visible })
    end)
    Menu:AddMenuInstance('Sub-TopBar', 'Square', { Position = BasePosition, Size = V2New(BaseSize.X, 10), Color = Colors.Primary.Dark, Filled = true, Visible = Visible })
    Menu:AddMenuInstance('Sub-TopBarTwo', 'Square', { Position = BasePosition + V2New(0, 10), Size = V2New(BaseSize.X, 20), Color = Colors.Primary.Main, Filled = true, Visible = Visible })
    Menu:AddMenuInstance('Sub-TopBarText', 'Text', { Size = 20, Position = shared.MenuDrawingData.Instances['Sub-TopBarTwo'].Position + V2New(15, -3), Text = Title or '', Color = Colors.Secondary.Light, Visible = Visible })
    Menu:AddMenuInstance('Sub-Filling', 'Square', { Size = BaseSize - V2New(0, 30), Position = BasePosition + V2New(0, 30), Filled = true, Color = Colors.Secondary.Main, Transparency = 0.75, Visible = Visible })
    if Options then
        for Index, Option in pairs(Options) do
            local function GetName(Name) return ('Sub-%s.%d'):format(Name, Index) end
            local Position = shared.MenuDrawingData.Instances['Sub-Filling'].Position + V2New(20, Index * 25 - 10)
            if Option.Type == 'Color' then
                local ColorPreview = Menu:AddMenuInstance(GetName('ColorPreview'), 'Circle', { Position = Position, Color = Option.Color, Radius = IsSynapse and 10 or 10, NumSides = 10, Filled = true, Visible = true })
                Menu:AddMenuInstance(GetName('Text'), 'Text', { Text = Option.Text, Position = ColorPreview.Position + V2New(15, -8), Size = 16, Color = Colors.Primary.Dark, Visible = true })
                UIButtons[#UIButtons + 1] = { FromSubMenu = true, Option = function() return Option.Function(ColorPreview, BasePosition + V2New(BaseSize.X, 0)) end, Instance = Menu:AddMenuInstance(Format('%s_Hitbox', GetName('Button')), 'Square', { Position = Position - V2New(20, 12), Size = V2New(BaseSize.X, 25), Visible = false }) }
            elseif Option.Type == 'Button' then
                UIButtons[#UIButtons + 1] = { FromSubMenu = true, Option = Option.Function, Instance = Menu:AddMenuInstance(Format('%s_Hitbox', GetName('Button')), 'Square', { Size = V2New(BaseSize.X, 20) - V2New(20, 0), Visible = true, Transparency = 0.5, Position = Position - V2New(10, 10), Color = Colors.Secondary.Light, Filled = true }) }
                Menu:AddMenuInstance(Format('%s_Text', GetName('Text')), 'Text', { Text = Option.Text, Size = 18, Position = Position + V2New(5, -10), Visible = true, Color = Colors.Primary.Dark })
            end
        end
    end
end

function SubMenu:Hide()
    self.Open = false
    for i, v in pairs(shared.MenuDrawingData.Instances) do
        if i:sub(1, 3) == 'Sub' then
            v.Visible = false
            if i:sub(4, 4) == ':' then v:Remove(); shared.MenuDrawingData.Instance[i] = nil end
        end
    end
    for i, Button in pairs(UIButtons) do if Button.FromSubMenu then UIButtons[i] = nil end end
    spawn(function()
        for i = 1, 10 do
            if shared.CurrentColorPicker then shared.CurrentColorPicker:Dispose() end
            task.wait(0.1)
        end
    end)
    CurrentColorPicker = nil
end

function CreateMenu(NewPosition)
    MenuLoaded = false; UIButtons = {}; Sliders = {}
    local BaseSize = V2New(300, 625)
    local BasePosition = NewPosition or V2New(Camera.ViewportSize.X / 8 - (BaseSize.X / 2), Camera.ViewportSize.Y / 2 - (BaseSize.Y / 2))
    BasePosition = V2New(math.clamp(BasePosition.X, 0, Camera.ViewportSize.X), math.clamp(BasePosition.Y, 0, Camera.ViewportSize.Y))

    Menu:AddMenuInstance('CrosshairX', 'Line', { Visible = false, Color = Color3.new(0, 1, 0), Transparency = 1, Thickness = 1 })
    Menu:AddMenuInstance('CrosshairY', 'Line', { Visible = false, Color = Color3.new(0, 1, 0), Transparency = 1, Thickness = 1 })
    delay(0.025, function()
    Menu:AddMenuInstance('Main', 'Square', { 
    Size = BaseSize, 
    Position = BasePosition, 
    Filled = false, 
    Color = Color3.fromHSV(0, 1, 1), 
    Thickness = 3, 
    Visible = true 
})
    end)
    Menu:AddMenuInstance('TopBar', 'Square', { Position = BasePosition, Size = V2New(BaseSize.X, 15), Color = Colors.Primary.Dark, Filled = true, Visible = true })
    Menu:AddMenuInstance('TopBarTwo', 'Square', { Position = BasePosition + V2New(0, 15), Size = V2New(BaseSize.X, 45), Color = Colors.Primary.Main, Filled = true, Visible = true })
    Menu:AddMenuInstance('TopBarText', 'Text', { Size = 25, Position = shared.MenuDrawingData.Instances.TopBarTwo.Position + V2New(25, 10), Text = 'Unnamed ESP', Color = Colors.Secondary.Light, Visible = true, Transparency = 1, Outline = true, OutlineOpacity = 0.5 })
    Menu:AddMenuInstance('TopBarTextBR', 'Text', { Size = 18, Position = shared.MenuDrawingData.Instances.TopBarTwo.Position + V2New(BaseSize.X - 75, 25), Text = 'by ic3w0lf', Color = Colors.Secondary.Light, Visible = true, Transparency = 1, Outline = true, OutlineOpacity = 0.5 })
    Menu:AddMenuInstance('Filling', 'Square', { Size = BaseSize - V2New(0, 60), Position = BasePosition + V2New(0, 60), Filled = true, Color = Colors.Secondary.Main, Transparency = 0.35, Visible = true })

    local CPos = 0
    GetTableData(Options)(function(i, v)
        if typeof(v.Value) == 'boolean' and not IsStringEmpty(v.Text) and v.Text ~= nil then
            CPos = CPos + 25
            local BaseSize = V2New(BaseSize.X, 30)
            local BasePosition = shared.MenuDrawingData.Instances.Filling.Position + V2New(30, v.Index * 25 - 10)
            UIButtons[#UIButtons + 1] = { Option = v, Instance = Menu:AddMenuInstance(Format('%s_Hitbox', v.Name), 'Square', { Position = BasePosition - V2New(30, 15), Size = BaseSize, Visible = false }) }
            Menu:AddMenuInstance(Format('%s_OuterCircle', v.Name), 'Circle', { Radius = 10, Position = BasePosition, Color = Colors.Secondary.Light, Filled = true, Visible = true })
            Menu:AddMenuInstance(Format('%s_InnerCircle', v.Name), 'Circle', { Radius = 7, Position = BasePosition, Color = Colors.Secondary.Dark, Filled = true, Visible = v.Value })
            Menu:AddMenuInstance(Format('%s_Text', v.Name), 'Text', { Text = v.Text, Size = 20, Position = BasePosition + V2New(20, -10), Visible = true, Color = Colors.Secondary.Light, Transparency = 1, Outline = true, OutlineOpacity = 0.5 })
        end
    end)
    GetTableData(Options)(function(i, v)
        if typeof(v.Value) == 'number' then
            CPos = CPos + 25
            local BaseSize = V2New(BaseSize.X, 30)
            local BasePosition = shared.MenuDrawingData.Instances.Filling.Position + V2New(0, CPos - 10)
            local Line = Menu:AddMenuInstance(Format('%s_SliderLine', v.Name), 'Square', { Transparency = 1, Color = Colors.Secondary.Light, Filled = true, Visible = true, Position = BasePosition + V2New(15, -5), Size = BaseSize - V2New(30, 10), Transparency = 0.5 })
            local Slider = Menu:AddMenuInstance(Format('%s_Slider', v.Name), 'Square', { Visible = true, Filled = true, Color = Colors.Primary.Dark, Size = V2New(5, Line.Size.Y), Transparency = 0.5 })
            local Text = Menu:AddMenuInstance(Format('%s_Text', v.Name), 'Text', { Text = v.Text, Size = 20, Center = true, Transparency = 1, Outline = true, OutlineOpacity = 0.5, Visible = true, Color = Colors.White }); Text.Position = Line.Position + (Line.Size / 2) - V2New(0, Text.TextBounds.Y / 1.75)
            local AMT = Menu:AddMenuInstance(Format('%s_AmountText', v.Name), 'Text', { Text = tostring(v.Value), Size = 22, Center = true, Transparency = 1, Outline = true, OutlineOpacity = 0.5, Visible = true, Color = Colors.White, Position = Text.Position })
            local CSlider = {Slider = Slider, Line = Line, Min = v.AllArgs[4], Max = v.AllArgs[5], Option = v}
            local Dummy = Instance.new('NumberValue')
            Dummy:GetPropertyChangedSignal('Value'):Connect(function() Text.Transparency = Dummy.Value; AMT.Transparency = 1 - Dummy.Value end)
            Dummy.Value = 1
            function CSlider:ShowValue(Bool) self.ShowingValue = Bool; TweenService:Create(Dummy, TweenInfo.new(0.5, Enum.EasingStyle.Quart, Enum.EasingDirection.Out), { Value = Bool and 0 or 1 }):Play() end
            Sliders[#Sliders + 1] = CSlider
            Slider.Position = Line.Position + V2New(35, 0)
            v.BaseSize = BaseSize; v.BasePosition = BasePosition
        end
    end)
    local FirstItem = false
    GetTableData(Options)(function(i, v)
        if typeof(v.Value) == 'EnumItem' then
            CPos = CPos + (not FirstItem and 30 or 25); FirstItem = true
            local BaseSize = V2New(BaseSize.X, FirstItem and 30 or 25)
            local BasePosition = shared.MenuDrawingData.Instances.Filling.Position + V2New(0, CPos - 10)
            UIButtons[#UIButtons + 1] = { Option = v, Instance = Menu:AddMenuInstance(Format('%s_Hitbox', v.Name), 'Square', { Size = V2New(BaseSize.X, 20) - V2New(30, 0), Visible = true, Transparency = 0.5, Position = BasePosition + V2New(15, -10), Color = Colors.Secondary.Light, Filled = true }) }
            local Text = Menu:AddMenuInstance(Format('%s_Text', v.Name), 'Text', { Text = v.Text, Size = 20, Position = BasePosition + V2New(20, -10), Visible = true, Color = Colors.Secondary.Light, Transparency = 1, Outline = true, OutlineOpacity = 0.5 })
            local BindText = Menu:AddMenuInstance(Format('%s_BindText', v.Name), 'Text', { Text = tostring(v.Value):match('%w+%.%w+%.(.+)'), Size = 20, Position = BasePosition, Visible = true, Color = Colors.Secondary.Light, Transparency = 1, Outline = true, OutlineOpacity = 0.5 })
            Options[i].BaseSize = BaseSize; Options[i].BasePosition = BasePosition
            BindText.Position = BasePosition + V2New(BaseSize.X - BindText.TextBounds.X - 20, -10)
        end
    end)
    GetTableData(Options)(function(i, v)
        if typeof(v.Value) == 'function' then
            local BaseSize = V2New(BaseSize.X, 30)
            local BasePosition = shared.MenuDrawingData.Instances.Filling.Position + V2New(0, CPos + (25 * v.AllArgs[4]) - 35)
            UIButtons[#UIButtons + 1] = { Option = v, Instance = Menu:AddMenuInstance(Format('%s_Hitbox', v.Name), 'Square', { Size = V2New(BaseSize.X, 20) - V2New(30, 0), Visible = true, Transparency = 0.5, Position = BasePosition + V2New(15, -10), Color = Colors.Secondary.Light, Filled = true }) }
            local Text = Menu:AddMenuInstance(Format('%s_Text', v.Name), 'Text', { Text = v.Text, Size = 20, Position = BasePosition + V2New(20, -10), Visible = true, Color = Colors.Secondary.Light, Transparency = 1, Outline = true, OutlineOpacity = 0.5 })
        end
    end)
    delay(0.1, function() MenuLoaded = true end)
    Menu:AddMenuInstance('Cursor1', 'Line', { Visible = false, Color = Color3.new(1, 0, 0), Transparency = 1, Thickness = 2 })
    Menu:AddMenuInstance('Cursor2', 'Line', { Visible = false, Color = Color3.new(1, 0, 0), Transparency = 1, Thickness = 2 })
    Menu:AddMenuInstance('Cursor3', 'Line', { Visible = false, Color = Color3.new(1, 0, 0), Transparency = 1, Thickness = 2 })
end

CreateMenu()
delay(0.1, function() SubMenu:Show(V2New()); SubMenu:Hide() end)

local DrawingScreenGui
if game:GetService("CoreGui"):FindFirstChild("Drawing") then
    DrawingScreenGui = game:GetService("CoreGui"):FindFirstChild("Drawing")
else
    DrawingScreenGui = Instance.new("ScreenGui")
    DrawingScreenGui.Name = "Drawing"
    DrawingScreenGui.Parent = game:GetService("CoreGui")
end

local function ToggleDrawingGUI()
    if DrawingScreenGui then
        DrawingScreenGui.Enabled = not DrawingScreenGui.Enabled
    end
end

shared.UESP_InputChangedCon = UserInputService.InputChanged:Connect(function(input)
    if input.UserInputType.Name == 'MouseMovement' and Options.MenuOpen.Value then
        for i, v in pairs(Sliders) do
            local Values = { v.Line.Position.X, v.Line.Position.Y, v.Line.Position.X + v.Line.Size.X, v.Line.Position.Y + v.Line.Size.Y }
            if MouseHoveringOver(Values) then v:ShowValue(true); else if not MouseHeld then v:ShowValue(false) end end
        end
    end
end)

shared.UESP_InputBeganCon = UserInputService.InputBegan:Connect(function(input)
    if input.UserInputType.Name == 'MouseButton1' and Options.MenuOpen.Value then
        MouseHeld = true
        local Bar = Menu:GetInstance('TopBar')
        local Values = { Bar.Position.X, Bar.Position.Y, Bar.Position.X + Bar.Size.X, Bar.Position.Y + Bar.Size.Y }
        if MouseHoveringOver(Values) then
            DraggingUI = true
            DragOffset = Menu:GetInstance('Main').Position - GetMouseLocation()
        else
            for i, v in pairs(Sliders) do
                local Values = { v.Line.Position.X, v.Line.Position.Y, v.Line.Position.X + v.Line.Size.X, v.Line.Position.Y + v.Line.Size.Y }
                if MouseHoveringOver(Values) then DraggingWhat = v; Dragging = true; break end
            end
            if not Dragging then
                local Values = { TracerPosition.X - 10, TracerPosition.Y - 10, TracerPosition.X + 10, TracerPosition.Y + 10 }
                if MouseHoveringOver(Values) then DragTracerPosition = true end
            end
        end
    end
end)

shared.UESP_InputEndedCon = UserInputService.InputEnded:Connect(function(input)
    if input.UserInputType.Name == 'MouseButton1' and Options.MenuOpen.Value then
        MouseHeld = false; DragTracerPosition = false
        local IgnoreOtherInput = false
        if SubMenu.Open and not MouseHoveringOver(SubMenu.Bounds) then
            if CurrentColorPicker and IsMouseOverDrawing(CurrentColorPicker.Drawings['Square-Background']()) then IgnoreOtherInput = true end
            if not IgnoreOtherInput then SubMenu:Hide() end
        end
        if not IgnoreOtherInput then
            for i, v in pairs(UIButtons) do
                if SubMenu.Open and MouseHoveringOver(SubMenu.Bounds) and not v.FromSubMenu then continue end
                local Values = { v.Instance.Position.X, v.Instance.Position.Y, v.Instance.Position.X + v.Instance.Size.X, v.Instance.Position.Y + v.Instance.Size.Y }
                if MouseHoveringOver(Values) then v.Option(); IgnoreOtherInput = true; break end
            end
            for i, v in pairs(Sliders) do
                if IgnoreOtherInput then break end
                local Values = { v.Line.Position.X, v.Line.Position.Y, v.Line.Position.X + v.Line.Size.X, v.Line.Position.Y + v.Line.Size.Y }
                if not MouseHoveringOver(Values) then v:ShowValue(false) end
            end
        end
    elseif input.UserInputType.Name == 'MouseButton2' and Options.MenuOpen.Value and not DragTracerPosition then
        local Values = { TracerPosition.X - 10, TracerPosition.Y - 10, TracerPosition.X + 10, TracerPosition.Y + 10 }
        if MouseHoveringOver(Values) then DragTracerPosition = false; TracerPosition = V2New(Camera.ViewportSize.X / 2, Camera.ViewportSize.Y - 135) end
    elseif input.UserInputType.Name == 'Keyboard' then
        if Binding then BindedKey = input.KeyCode; Binding = false
        elseif input.KeyCode == Options.MenuKey.Value or (input.KeyCode == Enum.KeyCode.Home and UserInputService:IsKeyDown(Enum.KeyCode.LeftControl)) then
            Options.MenuOpen()
            ToggleDrawingGUI()
        elseif input.KeyCode == Options.ToggleKey.Value then Options.Enabled()
        elseif input.KeyCode.Name == 'F1' and UserInputService:IsMouseButtonPressed(1) and shared.am_ic3 then
            local HD, LPlayer, LCharacter = 0.95
            for i, Player in pairs(Players:GetPlayers()) do
                local Character = GetCharacter(Player)
                if Player ~= LocalPlayer and Player ~= Spectating and Character and Character:FindFirstChild('HumanoidRootPart') then
                    local Head = Character:FindFirstChild('Head')
                    if Head then
                        local Distance = (Camera.CFrame.Position - Head.Position).Magnitude
                        if Distance > Options.MaxDistance.Value then continue end
                        local Direction = -(Camera.CFrame.Position - Mouse.Hit.Position).unit
                        local Relative = Character.Head.Position - Camera.CFrame.Position
                        local Unit = Relative.unit
                        local DP = Direction:Dot(Unit)
                        if DP > HD then HD = DP; LPlayer = Player; LCharacter = Character end
                    end
                end
            end
            if LPlayer and LPlayer ~= Spectating and LCharacter then Camera.CameraSubject = LCharacter.Head; Spectating = LPlayer
            elseif LocalPlayer.Character and LocalPlayer.Character:FindFirstChildOfClass('Humanoid') then Camera.CameraSubject = LocalPlayer.Character:FindFirstChildOfClass('Humanoid'); Spectating = nil end
        end
    end
end)

local function CameraCon()
    workspace.CurrentCamera:GetPropertyChangedSignal('ViewportSize'):Connect(function()
        TracerPosition = V2New(Camera.ViewportSize.X / 2, Camera.ViewportSize.Y - 135)
    end)
end
CameraCon()

local function ToggleMenu()
    if Options.MenuOpen.Value then
        GetTableData(shared.MenuDrawingData.Instances)(function(i, v) if OldData[v] then pcall(Set, v, 'Visible', true) end end)
    else
        GetTableData(shared.MenuDrawingData.Instances)(function(i, v) OldData[v] = v.Visible; if v.Visible then pcall(Set, v, 'Visible', false) end end)
    end
end

local LastRayIgnoreUpdate, RayIgnoreList = 0, {}
local function CheckRay(Instance, Distance, Position, Unit)
    local Pass = true; local Model = Instance
    if Distance > 999 then return false end
    if Instance.ClassName == 'Player' then Model = GetCharacter(Instance) end
    if not Model then Model = Instance.Parent; if Model.Parent == workspace then Model = Instance end end
    if not Model then return false end
    local _Ray = Ray.new(Position, Unit * Distance)
    if tick() - LastRayIgnoreUpdate > 3 then
        LastRayIgnoreUpdate = tick()
        table.clear(RayIgnoreList)
        table.insert(RayIgnoreList, LocalPlayer.Character)
        table.insert(RayIgnoreList, Camera)
        if Mouse.TargetFilter then table.insert(RayIgnoreList, Mouse.TargetFilter) end
        if #IgnoreList > 64 then while #IgnoreList > 64 do table.remove(IgnoreList, 1) end end
        for i, v in pairs(IgnoreList) do table.insert(RayIgnoreList, v) end
    end
    local Hit = workspace:FindPartOnRayWithIgnoreList(_Ray, RayIgnoreList)
    if Hit and not Hit:IsDescendantOf(Model) then
        Pass = false
        if Hit.Transparency >= 0.3 or not Hit.CanCollide and Hit.ClassName ~= 'Terrain' then table.insert(IgnoreList, Hit) end
    end
    return Pass
end

local function CheckTeam(Player)
    if Player.Neutral and LocalPlayer.Neutral then return true end
    return Player.TeamColor == LocalPlayer.TeamColor
end

local CustomTeam = CustomTeams[game.PlaceId]
if CustomTeam ~= nil then
    if CustomTeam.Initialize then ypcall(CustomTeam.Initialize) end
    CheckTeam = CustomTeam.CheckTeam
end

local function IsVisible(Player)
    if not Options.VisCheck.Value then return true end
    
    local character = GetCharacter(Player)
    if not character then return false end
    
    local head = character:FindFirstChild('Head')
    if not head then return false end
    
    local rootPart = character:FindFirstChild('HumanoidRootPart')
    if not rootPart then return false end
    
    local origin = Camera.CFrame.Position
    local targets = {
        head.Position,
        rootPart.Position,
        (head.Position + rootPart.Position) / 2
    }
    
    for _, target in pairs(targets) do
        local direction = (target - origin).unit
        local distance = (target - origin).Magnitude
        
        if distance < 5 then return true end
        
        local ray = Ray.new(origin, direction * distance)
        local hit, position = workspace:FindPartOnRayWithIgnoreList(ray, {
            LocalPlayer.Character,
            Camera,
            character
        })
        
        if not hit then
            return true
        end
        
        if hit:IsDescendantOf(character) then
            return true
        end
    end
    
    return false
end

local BillboardConnections = {}
local BillboardDrawings = {}

local function CreateBillboardText(player)
    if player == LocalPlayer then return end
    
    local Text = NewDrawing('Text'){
        Size = Options.TextSize.Value,
        Color = Color3.new(1, 1, 1),
        Center = true,
        Outline = Options.TextOutline.Value,
        OutlineOpacity = 0.5,
        Visible = false,
        Transparency = 1,
        ZIndex = 3,
        Font = Drawing.Fonts and Drawing.Fonts.Monospace or 3
    }
    
    BillboardDrawings[player] = {
        Text = Text
    }
    
    local conn = RunService.RenderStepped:Connect(function()
        local character = GetCharacter(player)
        local text = BillboardDrawings[player]
        
        if not text or not character or not Options.Enabled.Value then
            if text and text.Text then text.Text.Visible = false end
            return
        end
        
        local head = character:FindFirstChild('Head')
        if not head then
            text.Text.Visible = false
            return
        end
        
        if Options.VisCheck.Value and not IsVisible(player) then
            text.Text.Visible = false
            return
        end
        
        local Vector, OnScreen = Camera:WorldToViewportPoint(head.Position + V3New(0, 2.5 + Options.YOffset.Value / 100, 0))
        
        if OnScreen then
            local distance = (Camera.CFrame.Position - head.Position).Magnitude
            if distance > Options.MaxDistance.Value then
                text.Text.Visible = false
                return
            end
            
            local info = {}
            
            if Options.ShowName.Value then
                local name = player.Name
                if CustomPlayerTag then
                    local tag = CustomPlayerTag(player)
                    if tag and #tag > 0 then name = name .. tag end
                end
                table.insert(info, name)
            end
            
            if Options.ShowHealth.Value then
                local health = 100
                if GetHealth then
                    health = GetHealth(player) or 100
                elseif character:FindFirstChildOfClass('Humanoid') then
                    health = math.floor(character:FindFirstChildOfClass('Humanoid').Health)
                end
                table.insert(info, string.format('[%s HP]', health))
            end
            
            if Options.ShowDistance.Value then
                table.insert(info, string.format('[%sm]', math.floor(distance)))
            end
            
            if #info == 0 then
                text.Text.Visible = false
                return
            end
            
            local color
            if Rainbow then
                color = Color3.fromHSV(tick() * 128 % 255 / 255, 1, 1)
            elseif Options.ShowTeamColor.Value then
                color = player.TeamColor.Color
            elseif CheckTeam(player) then
                color = TeamColor
            else
                color = EnemyColor
            end
            
            text.Text.Text = table.concat(info, ' ')
            text.Text.Color = color
            text.Text.Size = Options.TextSize.Value
            text.Text.Outline = Options.TextOutline.Value
            text.Text.Position = V2New(Vector.X, Vector.Y)
            text.Text.Visible = true
        else
            text.Text.Visible = false
        end
    end)
    
    table.insert(BillboardConnections, conn)
end

local function RemoveBillboard(player)
    local text = BillboardDrawings[player]
    if text and text.Text then
        text.Text.Visible = false
        text.Text:Remove()
    end
    BillboardDrawings[player] = nil
end

local function CreateAllBillboards()
    for _, conn in pairs(BillboardConnections) do
        conn:Disconnect()
    end
    BillboardConnections = {}
    
    for _, text in pairs(BillboardDrawings) do
        if text and text.Text then
            text.Text.Visible = false
            text.Text:Remove()
        end
    end
    BillboardDrawings = {}
    
    for _, player in pairs(Players:GetPlayers()) do
        if player ~= LocalPlayer then
            CreateBillboardText(player)
        end
    end
end

Players.PlayerAdded:Connect(function(player)
    task.wait(0.5)
    CreateBillboardText(player)
end)

Players.PlayerRemoving:Connect(function(player)
    RemoveBillboard(player)
end)

LocalPlayer.CharacterAdded:Connect(function()
    task.wait(1)
    CreateAllBillboards()
end)

CreateAllBillboards()

local runService = game:GetService('RunService')
local players = game:GetService('Players')

local localPlayer = players.LocalPlayer
local camera = workspace.CurrentCamera

local newVector2, newColor3, newDrawing = Vector2.new, Color3.new, Drawing.new
local tan, rad = math.tan, math.rad
local round = function(...) local a = {}; for i,v in next, table.pack(...) do a[i] = math.round(v) end return unpack(a) end
local wtvp = function(...) local a, b = camera.WorldToViewportPoint(camera, ...) return newVector2(a.X, a.Y), b, a.Z end

local espCache = {}

local function GetESPColor(player)
    if Rainbow then
        return Color3.fromHSV(tick() * 128 % 255 / 255, 1, 1)
    elseif Options.ShowTeamColor and Options.ShowTeamColor.Value then 
        return player.TeamColor.Color
    elseif CheckTeam(player) then
        return TeamColor
    else
        return EnemyColor
    end
end

local function createEsp(player)
   local drawings = {}
   
   drawings.box = newDrawing('Square')
   drawings.box.Thickness = 1
   drawings.box.Filled = false
   drawings.box.Color = GetESPColor(player)
   drawings.box.Visible = false
   drawings.box.ZIndex = 2

   drawings.boxoutline = newDrawing('Square')
   drawings.boxoutline.Thickness = 3
   drawings.boxoutline.Filled = false
   drawings.boxoutline.Color = GetESPColor(player)
   drawings.boxoutline.Visible = false
   drawings.boxoutline.ZIndex = 1
   drawings.boxoutline.Transparency = 0.5

   espCache[player] = drawings
end

local function removeEsp(player)
   if rawget(espCache, player) then
       for _, drawing in next, espCache[player] do
           drawing:Remove()
       end
       espCache[player] = nil
   end
end

local function updateEsp(player, esp)
   local character = player and player.Character
   if character then
       local cframe = character:GetModelCFrame()
       local position, visible, depth = wtvp(cframe.Position)
       esp.box.Visible = visible
       esp.boxoutline.Visible = visible

       if cframe and visible then
           if Options.VisCheck.Value and not IsVisible(player) then
               esp.box.Visible = false
               esp.boxoutline.Visible = false
               return
           end
           
           local scaleFactor = 1 / (depth * tan(rad(camera.FieldOfView / 2)) * 2) * 1000
           local width, height = round(4 * scaleFactor, 5 * scaleFactor)
           local x, y = round(position.X, position.Y)

           local boxSize = newVector2(width, height)
           local boxPos = newVector2(round(x - width / 2, y - height / 2))
           
           local color = GetESPColor(player)
           
           esp.box.Size = boxSize
           esp.box.Position = boxPos
           esp.box.Color = color
           
           esp.boxoutline.Size = boxSize
           esp.boxoutline.Position = boxPos
           esp.boxoutline.Color = color
           esp.boxoutline.Transparency = 0.5
           
           local distance = (Camera.CFrame.Position - character:FindFirstChild('HumanoidRootPart').Position).Magnitude
           if distance > Options.MaxDistance.Value then
               esp.box.Visible = false
               esp.boxoutline.Visible = false
           end
       end
   else
       esp.box.Visible = false
       esp.boxoutline.Visible = false
   end
end

for _, player in next, players:GetPlayers() do
   if player ~= localPlayer then
       createEsp(player)
   end
end

players.PlayerAdded:Connect(function(player)
   createEsp(player)
end)

players.PlayerRemoving:Connect(function(player)
   removeEsp(player)
end)

runService:BindToRenderStep('BoxESP', Enum.RenderPriority.Camera.Value, function()
   for player, drawings in next, espCache do
       if drawings and player ~= localPlayer then
           updateEsp(player, drawings)
       end
   end
end)

local TracerConnections = {}
local TracerDrawings = {}

local function GetTracerColor(player)
    if Rainbow then
        return Color3.fromHSV(tick() * 128 % 255 / 255, 1, 1)
    elseif Options.ShowTeamColor and Options.ShowTeamColor.Value then 
        return player.TeamColor.Color
    elseif CheckTeam(player) then
        return TeamColor
    else
        return EnemyColor
    end
end

local function CreateTracers()
    for _, conn in pairs(TracerConnections) do
        conn:Disconnect()
    end
    for _, drawings in pairs(TracerDrawings) do
        if drawings.Tracer then
            drawings.Tracer.Visible = false
            drawings.Tracer:Remove()
        end
        if drawings.TracerOutline then
            drawings.TracerOutline.Visible = false
            drawings.TracerOutline:Remove()
        end
    end
    TracerConnections = {}
    TracerDrawings = {}
    
    for _, player in pairs(Players:GetPlayers()) do
        if player == LocalPlayer then continue end
        
        local TracerOutline = NewDrawing('Line'){
            Thickness = 3,
            Transparency = 0.5,
            Color = GetTracerColor(player),
            Visible = false
        }
        local Tracer = NewDrawing('Line'){
            Thickness = 1,
            Transparency = 0.7,
            Color = GetTracerColor(player),
            Visible = false
        }
        
        TracerDrawings[player] = {
            Tracer = Tracer,
            TracerOutline = TracerOutline
        }
        
        local conn = RunService.RenderStepped:Connect(function()
            local character = GetCharacter(player)
            if character and character:FindFirstChild('HumanoidRootPart') and Options.Enabled.Value and Options.ShowTracers.Value then
                local rootPart = character.HumanoidRootPart
                local Vector, OnScreen = Camera:WorldToViewportPoint((rootPart.CFrame * CFrame.new(0, -rootPart.Size.Y, 0)).Position)
                
                if Options.VisCheck.Value and not IsVisible(player) then
                    Tracer.Visible = false
                    TracerOutline.Visible = false
                    return
                end
                
                local color = GetTracerColor(player)
                Tracer.Color = color
                TracerOutline.Color = color
                TracerOutline.From = TracerPosition
                Tracer.From = TracerPosition
                
                if OnScreen then
                    Tracer.To = V2New(Vector.X, Vector.Y)
                    TracerOutline.To = V2New(Vector.X, Vector.Y)
                    
                    local distance = (Camera.CFrame.Position - rootPart.Position).Magnitude
                    local show = distance <= Options.MaxDistance.Value
                    
                    Tracer.Visible = show
                    TracerOutline.Visible = show
                else
                    local head = character:FindFirstChild('Head')
                    if head then
                        local OPos = Camera.CFrame:pointToObjectSpace(head.Position)
                        local AT = math.atan2(OPos.Y, OPos.X) + math.pi
                        OPos = CFrame.Angles(0, 0, AT):vectorToWorldSpace((CFrame.Angles(0, math.rad(89.9), 0):vectorToWorldSpace(V3New(0, 0, -1))))
                        local edgePos = WorldToViewport(Camera.CFrame:pointToWorldSpace(OPos))
                        Tracer.To = V2New(edgePos.X, edgePos.Y)
                        TracerOutline.To = V2New(edgePos.X, edgePos.Y)
                        
                        local distance = (Camera.CFrame.Position - head.Position).Magnitude
                        local show = distance <= Options.MaxDistance.Value
                        
                        Tracer.Visible = show
                        TracerOutline.Visible = show
                    else
                        Tracer.Visible = false
                        TracerOutline.Visible = false
                    end
                end
            else
                Tracer.Visible = false
                TracerOutline.Visible = false
            end
        end)
        
        table.insert(TracerConnections, conn)
    end
end

Players.PlayerAdded:Connect(function(player)
    task.wait(0.5)
    CreateTracers()
end)

Players.PlayerRemoving:Connect(function(player)
    local drawings = TracerDrawings[player]
    if drawings then
        if drawings.Tracer then
            drawings.Tracer.Visible = false
            drawings.Tracer:Remove()
        end
        if drawings.TracerOutline then
            drawings.TracerOutline.Visible = false
            drawings.TracerOutline:Remove()
        end
        TracerDrawings[player] = nil
    end
end)

LocalPlayer.CharacterAdded:Connect(function()
    task.wait(1)
    CreateTracers()
end)

CreateTracers()

local HeadDotConnections = {}
local HeadDotDrawings = {}

local function GetHeadDotColor(player)
    if Rainbow then
        return Color3.fromHSV(tick() * 128 % 255 / 255, 1, 1)
    elseif Options.ShowTeamColor and Options.ShowTeamColor.Value then 
        return player.TeamColor.Color
    elseif CheckTeam(player) then
        return TeamColor
    else
        return EnemyColor
    end
end

local function CreateHeadDots()
    for _, conn in pairs(HeadDotConnections) do
        conn:Disconnect()
    end
    for _, drawings in pairs(HeadDotDrawings) do
        if drawings.Dot then
            drawings.Dot.Visible = false
            drawings.Dot:Remove()
        end
        if drawings.DotOutline then
            drawings.DotOutline.Visible = false
            drawings.DotOutline:Remove()
        end
    end
    HeadDotConnections = {}
    HeadDotDrawings = {}
    
    for _, player in pairs(Players:GetPlayers()) do
        if player == LocalPlayer then continue end
        
        local DotOutline = NewDrawing('Circle'){
            Radius = 4,
            Thickness = 3,
            Filled = false,
            Color = GetHeadDotColor(player),
            Visible = false,
            ZIndex = 1,
            NumSides = 12,
            Transparency = 0.5
        }
        
        local Dot = NewDrawing('Circle'){
            Radius = 2,
            Thickness = 0,
            Filled = true,
            Color = GetHeadDotColor(player),
            Visible = false,
            ZIndex = 2,
            NumSides = 12
        }
        
        HeadDotDrawings[player] = {
            Dot = Dot,
            DotOutline = DotOutline
        }
        
        local conn = RunService.RenderStepped:Connect(function()
            local character = GetCharacter(player)
            if character and Options.Enabled.Value and Options.ShowDot.Value then
                local head = character:FindFirstChild('Head')
                if head then
                    local Vector, OnScreen = Camera:WorldToViewportPoint(head.Position)
                    
                    if OnScreen then
                        if Options.VisCheck.Value and not IsVisible(player) then
                            Dot.Visible = false
                            DotOutline.Visible = false
                            return
                        end
                        
                        local color = GetHeadDotColor(player)
                        
                        Dot.Color = color
                        DotOutline.Color = color
                        
                        local pos = V2New(Vector.X, Vector.Y)
                        Dot.Position = pos
                        DotOutline.Position = pos
                        
                        local distance = (Camera.CFrame.Position - head.Position).Magnitude
                        local show = distance <= Options.MaxDistance.Value
                        
                        Dot.Visible = show
                        DotOutline.Visible = show
                    else
                        Dot.Visible = false
                        DotOutline.Visible = false
                    end
                else
                    Dot.Visible = false
                    DotOutline.Visible = false
                end
            else
                if HeadDotDrawings[player] then
                    HeadDotDrawings[player].Dot.Visible = false
                    HeadDotDrawings[player].DotOutline.Visible = false
                end
            end
        end)
        
        table.insert(HeadDotConnections, conn)
    end
end

Players.PlayerAdded:Connect(function(player)
    task.wait(0.5)
    CreateHeadDots()
end)

Players.PlayerRemoving:Connect(function(player)
    local drawings = HeadDotDrawings[player]
    if drawings then
        if drawings.Dot then
            drawings.Dot.Visible = false
            drawings.Dot:Remove()
        end
        if drawings.DotOutline then
            drawings.DotOutline.Visible = false
            drawings.DotOutline:Remove()
        end
        HeadDotDrawings[player] = nil
    end
end)

LocalPlayer.CharacterAdded:Connect(function()
    task.wait(1)
    CreateHeadDots()
end)

CreateHeadDots()

local LastInvalidCheck = 0
local function Update()
    if tick() - LastInvalidCheck > 0.3 then
        LastInvalidCheck = tick()
        if Camera.Parent ~= workspace then Camera = workspace.CurrentCamera; CameraCon(); WTVP = Camera.WorldToViewportPoint end
    end

    if Options.MenuOpen.Value then
        local Main = Menu:GetInstance('Main')
        if Main then
            if tick() - (shared.LastRainbowUpdate or 0) > 0.05 then
                shared.LastRainbowUpdate = tick()
                local hue = (tick() * 0.08) % 1
                Main.Color = Color3.fromHSV(hue, 1, 1)
            end
        end
    end

    local CX = Menu:GetInstance('CrosshairX'); local CY = Menu:GetInstance('CrosshairY')
    if Options.Crosshair.Value then
        CX.Visible = true; CY.Visible = true
        CX.To = V2New((Camera.ViewportSize.X / 2) - 8, (Camera.ViewportSize.Y / 2))
        CX.From = V2New((Camera.ViewportSize.X / 2) + 8, (Camera.ViewportSize.Y / 2))
        CY.To = V2New((Camera.ViewportSize.X / 2), (Camera.ViewportSize.Y / 2) - 8)
        CY.From = V2New((Camera.ViewportSize.X / 2), (Camera.ViewportSize.Y / 2) + 8)
    else CX.Visible = false; CY.Visible = false end

    if Options.MenuOpen.Value and MenuLoaded then
        local MLocation = GetMouseLocation()
        
        local MainInstance = Menu:GetInstance('Main')
        local Values = { MainInstance.Position.X, MainInstance.Position.Y, MainInstance.Position.X + MainInstance.Size.X, MainInstance.Position.Y + MainInstance.Size.Y }
        if MainInstance and (MouseHoveringOver(Values) or (SubMenu.Open and MouseHoveringOver(SubMenu.Bounds))) then
            Debounce.CursorVis = true
            Menu:UpdateMenuInstance('Cursor1'){ Visible = true, From = V2New(MLocation.x, MLocation.y), To = V2New(MLocation.x + 5, MLocation.y + 6) }
            Menu:UpdateMenuInstance('Cursor2'){ Visible = true, From = V2New(MLocation.x, MLocation.y), To = V2New(MLocation.x, MLocation.y + 8) }
            Menu:UpdateMenuInstance('Cursor3'){ Visible = true, From = V2New(MLocation.x, MLocation.y + 6), To = V2New(MLocation.x + 5, MLocation.y + 5) }
        else
            if Debounce.CursorVis then Debounce.CursorVis = false
                Menu:UpdateMenuInstance('Cursor1'){Visible = false}; Menu:UpdateMenuInstance('Cursor2'){Visible = false}; Menu:UpdateMenuInstance('Cursor3'){Visible = false}
            end
        end
        if MouseHeld then
            local MousePos = GetMouseLocation()
            if Dragging then
                DraggingWhat.Slider.Position = V2New(math.clamp(MLocation.X - DraggingWhat.Slider.Size.X / 2, DraggingWhat.Line.Position.X, DraggingWhat.Line.Position.X + DraggingWhat.Line.Size.X - DraggingWhat.Slider.Size.X), DraggingWhat.Slider.Position.Y)
                local Percent = (DraggingWhat.Slider.Position.X - DraggingWhat.Line.Position.X) / ((DraggingWhat.Line.Position.X + DraggingWhat.Line.Size.X - DraggingWhat.Line.Position.X) - DraggingWhat.Slider.Size.X)
                local Value = CalculateValue(DraggingWhat.Min, DraggingWhat.Max, Percent)
                DraggingWhat.Option(Value)
            elseif DraggingUI then
                Debounce.UIDrag = true
                local Main = Menu:GetInstance('Main')
                Main.Position = MousePos + DragOffset
            elseif DragTracerPosition then TracerPosition = MousePos end
        else
            Dragging = false; DragTracerPosition = false
            if DraggingUI and Debounce.UIDrag then Debounce.UIDrag = false; DraggingUI = false; CreateMenu(Menu:GetInstance('Main').Position) end
        end
        if not Debounce.Menu then Debounce.Menu = true; ToggleMenu() end
    elseif Debounce.Menu and not Options.MenuOpen.Value then
        Debounce.Menu = false; ToggleMenu()
    else
        if Debounce.CursorVis then Debounce.CursorVis = false
            Menu:UpdateMenuInstance('Cursor1'){Visible = false}; Menu:UpdateMenuInstance('Cursor2'){Visible = false}; Menu:UpdateMenuInstance('Cursor3'){Visible = false}
        end
    end
end
RunService:UnbindFromRenderStep(GetDataName)
RunService:UnbindFromRenderStep(UpdateName)

RunService:BindToRenderStep(UpdateName, 199, Update)

Features & Information

Unnamed esp

Community Comments (0)

No comments yet for this script.

More Scripts for Universal Scripts