M
Description
I dedicate any and all copyright interest in this software to the public domain. I make this dedication for the benefit of the public at large and to the detriment of my heirs and successors. I intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. https://unlicense.org/
GAME💥Global Anarchy [Early Access]
UPDATEDOct 10, 2026
ACCESSKeyless
PLATFORMDesktop
Script source Luau
-- [[ BloxScripts Risk Notice ]]
-- This script has not been verified by BloxScripts.fun. Deal with caution.
--
-- Stay safe:
-- • Never log in on unofficial Roblox sites or lookalike domains.
-- • Real Roblox links use roblox.com (check the .com ending).
-- • Treat fake Roblox login / "claim reward" pages as phishing.
-- [[ End BloxScripts Risk Notice ]]
local ReplicatedFirst = game:GetService("ReplicatedFirst")
local CustomMeshCharacter = require(ReplicatedFirst.GunSystemPlugins.CustomMeshCharacter)
local LocalFriendlyService = require(ReplicatedFirst.Core.Services.LocalFriendlyService)
local Enemy = {}
Enemy.__index = Enemy
function Enemy.new(player, char)
local self = setmetatable({}, Enemy)
self.Player = player
self.Character = char
return self
end
local function GetEnemyTargets()
local result = {}
local enemies = LocalFriendlyService:GetEnemyPlayers()
for _, player in enemies do
if player:GetAttribute("Dead") then continue end
local char = CustomMeshCharacter:GetWorldCharacterFromPlayer(player)
if not char then continue end
table.insert(result, Enemy.new(player, char))
end
return result
end
local ESP = {
Config = {
ZIndex = 2,
Enabled = true,
ShowBoxes = true,
BoxThickness = 1,
FontSize = 12,
BoxColor = Color3.new(1, 1, 1),
ToolIconSize = 16
},
Callbacks = {
getPartsToRenderCallback = nil,
},
_activeObjects = {},
_drawingObjects = {},
_cache = {
parts = {},
lastUpdate = 0,
updateInterval = 0.1
},
_connections = {}
}
if DrawingImmediate then
function ESP:WorldToScreen(worldPosition)
local camera = workspace.CurrentCamera;
if not camera then
return nil
end;
local vector, onScreen = camera:WorldToViewportPoint(worldPosition)
if onScreen and vector.Z > 0 then
return Vector2.new(vector.X, vector.Y), vector.Z
end;
return nil, nil
end;
function ESP:GetPartBoxSize(part)
if not part then return 2, 2 end
local camera = workspace.CurrentCamera
if not camera then return 2, 2 end
local partPosition
if part:IsA("BasePart") then
partPosition = part.Position
elseif part:IsA("Model") then
partPosition = part:GetPivot().Position
else
return 2, 2
end
local distance = (camera.CFrame.Position - partPosition).Magnitude
if distance <= 0 then return 2, 2 end
local height = (camera.ViewportSize.Y / distance) * (4 / math.tan(math.rad(camera.FieldOfView * 0.5)))
return height * 0.4, height
end
function ESP:DrawBox(part, screenPos, boxWidth, boxHeight)
if not self.Config.ShowBoxes then
return
end;
local topLeft = Vector2.new(screenPos.X - (boxWidth / 2), screenPos.Y - boxHeight)
local boxColor = self.Config.BoxColor;
DrawingImmediate.Rectangle(topLeft, Vector2.new(boxWidth, boxHeight), boxColor, 1, 0, self.Config.BoxThickness)
local accentSize = math.min(10, boxWidth * 0.2)
local accentColor = Color3.new(1, 1, 1)
DrawingImmediate.Line(topLeft, Vector2.new(topLeft.X + accentSize, topLeft.Y), accentColor, 0.8, 2)
DrawingImmediate.Line(topLeft, Vector2.new(topLeft.X, topLeft.Y + accentSize), accentColor, 0.8, 2)
local topRight = Vector2.new(topLeft.X + boxWidth, topLeft.Y)
DrawingImmediate.Line(Vector2.new(topRight.X - accentSize, topRight.Y), topRight, accentColor, 0.8, 2)
DrawingImmediate.Line(topRight, Vector2.new(topRight.X, topRight.Y + accentSize), accentColor, 0.8, 2)
local bottomLeft = Vector2.new(topLeft.X, topLeft.Y + boxHeight)
DrawingImmediate.Line(bottomLeft, Vector2.new(bottomLeft.X + accentSize, bottomLeft.Y), accentColor, 0.8, 2)
DrawingImmediate.Line(bottomLeft, Vector2.new(bottomLeft.X, bottomLeft.Y - accentSize), accentColor, 0.8, 2)
local bottomRight = Vector2.new(topLeft.X + boxWidth, topLeft.Y + boxHeight)
DrawingImmediate.Line(Vector2.new(bottomRight.X - accentSize, bottomRight.Y), bottomRight, accentColor, 0.8, 2)
DrawingImmediate.Line(bottomRight, Vector2.new(bottomRight.X, bottomRight.Y - accentSize), accentColor, 0.8, 2)
end;
function ESP:_UpdateCache()
local currentTime = tick()
if currentTime - self._cache.lastUpdate < self._cache.updateInterval then
return
end;
self._cache.lastUpdate = currentTime;
self._cache.parts = {}
if self.Callbacks.getPartsToRenderCallback then
local parts = self.Callbacks.getPartsToRenderCallback()
if parts then
for i, part in ipairs(parts) do
self._cache.parts[#self._cache.parts + 1] = part;
end
end
end
end;
function ESP:_OnRender()
if not self.Config.Enabled then
return
end;
self:_UpdateCache()
for _, part in ipairs(self._cache.parts) do
if part and part.Parent then
local partPosition
if part:IsA("BasePart") then
partPosition = part.Position
elseif part:IsA("Model") then
partPosition = part:GetPivot().Position
end
local screenPos = self:WorldToScreen(partPosition)
if screenPos then
local w, h = self:GetPartBoxSize(part)
self:DrawBox(part, screenPos, w, h)
end
end
end;
for _, obj in ipairs(self._activeObjects) do
if obj.type == "circle" and obj.position then
local screenPos = self:WorldToScreen(obj.position)
if screenPos then
DrawingImmediate.Circle(screenPos, obj.radius, obj.color, 1, 32, 2)
end
elseif obj.type == "line" and obj.from and obj.to then
local fromScreen = self:WorldToScreen(obj.from)
local toScreen = self:WorldToScreen(obj.to)
if fromScreen and toScreen then
DrawingImmediate.Line(fromScreen, toScreen, obj.color, 1, obj.thickness or 1)
end
end
end
end;
function ESP:SetGetPartsToRenderCallback(callback)
self.Callbacks.getPartsToRenderCallback = callback
end;
function ESP:AddObject(object)
self._activeObjects[#self._activeObjects + 1] = object;
return object
end;
function ESP:RemoveObject(object)
for i, obj in ipairs(self._activeObjects) do
if obj == object then
table.remove(self._activeObjects, i)
break
end
end
end;
function ESP:ClearObjects()
self._activeObjects = {}
end;
function ESP:SetConfig(newConfig)
for k, v in pairs(newConfig) do
self.Config[k] = v
end
end;
function ESP:Toggle()
self.Config.Enabled = not self.Config.Enabled;
return self.Config.Enabled
end;
function ESP:Init()
if self._signal then
self:_Cleanup()
end;
self._signal = DrawingImmediate.GetPaint(self.Config.ZIndex)
local connection = self._signal:Connect(function()
self:_OnRender()
end)
self._connections[#self._connections + 1] = connection
end;
function ESP:_Cleanup()
for _, conn in ipairs(self._connections) do
conn:Disconnect()
end;
self._connections = {}
self._signal = nil
end;
function ESP:Destroy()
self:_Cleanup()
self._activeObjects = {}
self:ClearCallbacks()
self._cache = {
parts = {},
lastUpdate = 0,
updateInterval = 0.1
}
end;
function ESP:ForceUpdate()
self._cache.lastUpdate = 0;
self:_UpdateCache()
end
else
if not Drawing then
local drawingUI = Instance.new("ScreenGui", game:GetService("CoreGui"))
drawingUI.Name = "Drawing"
drawingUI.IgnoreGuiInset = true
drawingUI.DisplayOrder = 0x7fffffff
local drawingIndex = 0
local baseDrawingObj = setmetatable({
Visible = true,
ZIndex = 0,
Transparency = 1,
Color = Color3.new(),
Remove = function(self)
setmetatable(self, nil)
end,
Destroy = function(self)
setmetatable(self, nil)
end
}, {
__add = function(t1, t2)
local result = table.clone(t1)
for index, value in t2 do
result[index] = value
end
return result
end
})
local drawingFontsEnum = {
[0] = Font.fromEnum(Enum.Font.Roboto),
[1] = Font.fromEnum(Enum.Font.Legacy),
[2] = Font.fromEnum(Enum.Font.SourceSans),
[3] = Font.fromEnum(Enum.Font.RobotoMono),
}
local function convertTransparency(transparency)
return math.clamp(1 - transparency, 0, 1)
end
local DrawingLib = {}
DrawingLib.Fonts = {
["UI"] = 0,
["System"] = 1,
["Plex"] = 2,
["Monospace"] = 3
}
function DrawingLib.new(drawingType)
drawingIndex += 1
if drawingType == "Line" then
local lineObj = ({
From = Vector2.zero,
To = Vector2.zero,
Thickness = 1
} + baseDrawingObj)
local lineFrame = Instance.new("Frame")
lineFrame.Name = drawingIndex
lineFrame.AnchorPoint = (Vector2.one * .5)
lineFrame.BorderSizePixel = 0
lineFrame.BackgroundColor3 = lineObj.Color
lineFrame.Visible = lineObj.Visible
lineFrame.ZIndex = lineObj.ZIndex
lineFrame.BackgroundTransparency = convertTransparency(lineObj.Transparency)
lineFrame.Size = UDim2.new()
lineFrame.Parent = drawingUI
return setmetatable({__type = "Drawing Object"}, {
__newindex = function(_, index, value)
if typeof(lineObj[index]) == "nil" then return end
if index == "From" then
local direction = (lineObj.To - value)
local center = (lineObj.To + value) / 2
local distance = direction.Magnitude
local theta = math.deg(math.atan2(direction.Y, direction.X))
lineFrame.Position = UDim2.fromOffset(center.X, center.Y)
lineFrame.Rotation = theta
lineFrame.Size = UDim2.fromOffset(distance, lineObj.Thickness)
elseif index == "To" then
local direction = (value - lineObj.From)
local center = (value + lineObj.From) / 2
local distance = direction.Magnitude
local theta = math.deg(math.atan2(direction.Y, direction.X))
lineFrame.Position = UDim2.fromOffset(center.X, center.Y)
lineFrame.Rotation = theta
lineFrame.Size = UDim2.fromOffset(distance, lineObj.Thickness)
elseif index == "Thickness" then
local distance = (lineObj.To - lineObj.From).Magnitude
lineFrame.Size = UDim2.fromOffset(distance, value)
elseif index == "Visible" then
lineFrame.Visible = value
elseif index == "ZIndex" then
lineFrame.ZIndex = value
elseif index == "Transparency" then
lineFrame.BackgroundTransparency = convertTransparency(value)
elseif index == "Color" then
lineFrame.BackgroundColor3 = value
end
lineObj[index] = value
end,
__index = function(self, index)
if index == "Remove" or index == "Destroy" then
return function()
lineFrame:Destroy()
lineObj.Remove(self)
return lineObj:Remove()
end
end
return lineObj[index]
end,
__tostring = function() return "Drawing" end
})
elseif drawingType == "Text" then
local textObj = ({
Text = "",
Font = DrawingLib.Fonts.UI,
Size = 0,
Position = Vector2.zero,
Center = false,
Outline = false,
OutlineColor = Color3.new()
} + baseDrawingObj)
local textLabel, uiStroke = Instance.new("TextLabel"), Instance.new("UIStroke")
textLabel.Name = drawingIndex
textLabel.AnchorPoint = (Vector2.one * .5)
textLabel.BorderSizePixel = 0
textLabel.BackgroundTransparency = 1
textLabel.Visible = textObj.Visible
textLabel.TextColor3 = textObj.Color
textLabel.TextTransparency = convertTransparency(textObj.Transparency)
textLabel.ZIndex = textObj.ZIndex
textLabel.FontFace = drawingFontsEnum[textObj.Font]
textLabel.TextSize = textObj.Size
textLabel:GetPropertyChangedSignal("TextBounds"):Connect(function()
local textBounds = textLabel.TextBounds
local offset = textBounds / 2
textLabel.Size = UDim2.fromOffset(textBounds.X, textBounds.Y)
textLabel.Position = UDim2.fromOffset(textObj.Position.X + (if not textObj.Center then offset.X else 0), textObj.Position.Y + offset.Y)
end)
uiStroke.Thickness = 1
uiStroke.Enabled = textObj.Outline
uiStroke.Color = textObj.Color
textLabel.Parent, uiStroke.Parent = drawingUI, textLabel
return setmetatable({__type = "Drawing Object"}, {
__newindex = function(_, index, value)
if typeof(textObj[index]) == "nil" then return end
if index == "Text" then
textLabel.Text = value
elseif index == "Font" then
value = math.clamp(value, 0, 3)
textLabel.FontFace = drawingFontsEnum[value]
elseif index == "Size" then
textLabel.TextSize = value
elseif index == "Position" then
local offset = textLabel.TextBounds / 2
textLabel.Position = UDim2.fromOffset(value.X + (if not textObj.Center then offset.X else 0), value.Y + offset.Y)
elseif index == "Center" then
local position = (
if value then
workspace.CurrentCamera.ViewportSize / 2
else
textObj.Position
)
textLabel.Position = UDim2.fromOffset(position.X, position.Y)
elseif index == "Outline" then
uiStroke.Enabled = value
elseif index == "OutlineColor" then
uiStroke.Color = value
elseif index == "Visible" then
textLabel.Visible = value
elseif index == "ZIndex" then
textLabel.ZIndex = value
elseif index == "Transparency" then
local transparency = convertTransparency(value)
textLabel.TextTransparency = transparency
uiStroke.Transparency = transparency
elseif index == "Color" then
textLabel.TextColor3 = value
end
textObj[index] = value
end,
__index = function(self, index)
if index == "Remove" or index == "Destroy" then
return function()
textLabel:Destroy()
textObj.Remove(self)
return textObj:Remove()
end
elseif index == "TextBounds" then
return textLabel.TextBounds
end
return textObj[index]
end,
__tostring = function() return "Drawing" end
})
elseif drawingType == "Circle" then
local circleObj = ({
Radius = 150,
Position = Vector2.zero,
Thickness = .7,
Filled = false
} + baseDrawingObj)
local circleFrame, uiCorner, uiStroke = Instance.new("Frame"), Instance.new("UICorner"), Instance.new("UIStroke")
circleFrame.Name = drawingIndex
circleFrame.AnchorPoint = (Vector2.one * .5)
circleFrame.BorderSizePixel = 0
circleFrame.BackgroundTransparency = (if circleObj.Filled then convertTransparency(circleObj.Transparency) else 1)
circleFrame.BackgroundColor3 = circleObj.Color
circleFrame.Visible = circleObj.Visible
circleFrame.ZIndex = circleObj.ZIndex
uiCorner.CornerRadius = UDim.new(1, 0)
circleFrame.Size = UDim2.fromOffset(circleObj.Radius, circleObj.Radius)
uiStroke.Thickness = circleObj.Thickness
uiStroke.Enabled = not circleObj.Filled
uiStroke.ApplyStrokeMode = Enum.ApplyStrokeMode.Border
circleFrame.Parent, uiCorner.Parent, uiStroke.Parent = drawingUI, circleFrame, circleFrame
return setmetatable({__type = "Drawing Object"}, {
__newindex = function(_, index, value)
if typeof(circleObj[index]) == "nil" then return end
if index == "Radius" then
local radius = value * 2
circleFrame.Size = UDim2.fromOffset(radius, radius)
elseif index == "Position" then
circleFrame.Position = UDim2.fromOffset(value.X, value.Y)
elseif index == "Thickness" then
value = math.clamp(value, .6, 0x7fffffff)
uiStroke.Thickness = value
elseif index == "Filled" then
circleFrame.BackgroundTransparency = (if value then convertTransparency(circleObj.Transparency) else 1)
uiStroke.Enabled = not value
elseif index == "Visible" then
circleFrame.Visible = value
elseif index == "ZIndex" then
circleFrame.ZIndex = value
elseif index == "Transparency" then
local transparency = convertTransparency(value)
circleFrame.BackgroundTransparency = (if circleObj.Filled then transparency else 1)
uiStroke.Transparency = transparency
elseif index == "Color" then
circleFrame.BackgroundColor3 = value
uiStroke.Color = value
end
circleObj[index] = value
end,
__index = function(self, index)
if index == "Remove" or index == "Destroy" then
return function()
circleFrame:Destroy()
circleObj.Remove(self)
return circleObj:Remove()
end
end
return circleObj[index]
end,
__tostring = function() return "Drawing" end
})
elseif drawingType == "Square" then
local squareObj = ({
Size = Vector2.zero,
Position = Vector2.zero,
Thickness = .7,
Filled = false
} + baseDrawingObj)
local squareFrame, uiStroke = Instance.new("Frame"), Instance.new("UIStroke")
squareFrame.Name = drawingIndex
squareFrame.BorderSizePixel = 0
squareFrame.BackgroundTransparency = (if squareObj.Filled then convertTransparency(squareObj.Transparency) else 1)
squareFrame.ZIndex = squareObj.ZIndex
squareFrame.BackgroundColor3 = squareObj.Color
squareFrame.Visible = squareObj.Visible
uiStroke.Thickness = squareObj.Thickness
uiStroke.Enabled = not squareObj.Filled
uiStroke.LineJoinMode = Enum.LineJoinMode.Miter
squareFrame.Parent, uiStroke.Parent = drawingUI, squareFrame
return setmetatable({__type = "Drawing Object"}, {
__newindex = function(_, index, value)
if typeof(squareObj[index]) == "nil" then return end
if index == "Size" then
squareFrame.Size = UDim2.fromOffset(value.X, value.Y)
elseif index == "Position" then
squareFrame.Position = UDim2.fromOffset(value.X, value.Y)
elseif index == "Thickness" then
value = math.clamp(value, 0.6, 0x7fffffff)
uiStroke.Thickness = value
elseif index == "Filled" then
squareFrame.BackgroundTransparency = (if value then convertTransparency(squareObj.Transparency) else 1)
uiStroke.Enabled = not value
elseif index == "Visible" then
squareFrame.Visible = value
elseif index == "ZIndex" then
squareFrame.ZIndex = value
elseif index == "Transparency" then
local transparency = convertTransparency(value)
squareFrame.BackgroundTransparency = (if squareObj.Filled then transparency else 1)
uiStroke.Transparency = transparency
elseif index == "Color" then
uiStroke.Color = value
squareFrame.BackgroundColor3 = value
end
squareObj[index] = value
end,
__index = function(self, index)
if index == "Remove" or index == "Destroy" then
return function()
squareFrame:Destroy()
squareObj.Remove(self)
return squareObj:Remove()
end
end
return squareObj[index]
end,
__tostring = function() return "Drawing" end
})
elseif drawingType == "Image" then
local imageObj = ({
Data = "",
Size = Vector2.zero,
Position = Vector2.zero
} + baseDrawingObj)
local imageFrame = Instance.new("ImageLabel")
imageFrame.Name = drawingIndex
imageFrame.BorderSizePixel = 0
imageFrame.ScaleType = Enum.ScaleType.Stretch
imageFrame.BackgroundTransparency = 1
imageFrame.Visible = imageObj.Visible
imageFrame.ZIndex = imageObj.ZIndex
imageFrame.ImageTransparency = convertTransparency(imageObj.Transparency)
imageFrame.ImageColor3 = imageObj.Color
imageFrame.Parent = drawingUI
return setmetatable({__type = "Drawing Object"}, {
__newindex = function(_, index, value)
if typeof(imageObj[index]) == "nil" then return end
if index == "Data" then
imageFrame.Image = value
elseif index == "Size" then
imageFrame.Size = UDim2.fromOffset(value.X, value.Y)
elseif index == "Position" then
imageFrame.Position = UDim2.fromOffset(value.X, value.Y)
elseif index == "Visible" then
imageFrame.Visible = value
elseif index == "ZIndex" then
imageFrame.ZIndex = value
elseif index == "Transparency" then
imageFrame.ImageTransparency = convertTransparency(value)
elseif index == "Color" then
imageFrame.ImageColor3 = value
end
imageObj[index] = value
end,
__index = function(self, index)
if index == "Remove" or index == "Destroy" then
return function()
imageFrame:Destroy()
imageObj.Remove(self)
return imageObj:Remove()
end
end
return imageObj[index]
end,
__tostring = function() return "Drawing" end
})
elseif drawingType == "Quad" then
local QuadProperties = ({
Thickness = 1,
PointA = Vector2.new();
PointB = Vector2.new();
PointC = Vector2.new();
PointD = Vector2.new();
Filled = false;
} + baseDrawingObj)
local PointA = DrawingLib.new("Line")
local PointB = DrawingLib.new("Line")
local PointC = DrawingLib.new("Line")
local PointD = DrawingLib.new("Line")
return setmetatable({__type = "Drawing Object"}, {
__newindex = function(self, Property, Value)
if Property == "Thickness" then
PointA.Thickness = Value
PointB.Thickness = Value
PointC.Thickness = Value
PointD.Thickness = Value
end
if Property == "PointA" then
PointA.From = Value
PointB.To = Value
end
if Property == "PointB" then
PointB.From = Value
PointC.To = Value
end
if Property == "PointC" then
PointC.From = Value
PointD.To = Value
end
if Property == "PointD" then
PointD.From = Value
PointA.To = Value
end
if Property == "Visible" then
PointA.Visible = true
PointB.Visible = true
PointC.Visible = true
PointD.Visible = true
end
if Property == "Filled" then
PointA.BackgroundTransparency = 1
PointB.BackgroundTransparency = 1
PointC.BackgroundTransparency = 1
PointD.BackgroundTransparency = 1
end
if Property == "Color" then
PointA.Color = Value
PointB.Color = Value
PointC.Color = Value
PointD.Color = Value
end
if (Property == "ZIndex") then
PointA.ZIndex = Value
PointB.ZIndex = Value
PointC.ZIndex = Value
PointD.ZIndex = Value
end
end,
__index = function(self, Property)
if (string.lower(tostring(Property)) == "remove") then
return (function()
PointA:Remove();
PointB:Remove();
PointC:Remove();
PointD:Remove();
end)
end
return QuadProperties[Property]
end
});
elseif drawingType == "Triangle" then
local triangleObj = ({
PointA = Vector2.zero,
PointB = Vector2.zero,
PointC = Vector2.zero,
Thickness = 1,
Filled = false
} + baseDrawingObj)
local _linePoints = {}
_linePoints.A = DrawingLib.new("Line")
_linePoints.B = DrawingLib.new("Line")
_linePoints.C = DrawingLib.new("Line")
return setmetatable({__type = "Drawing Object"}, {
__tostring = function() return "Drawing" end,
__newindex = function(_, index, value)
if typeof(triangleObj[index]) == "nil" then return end
if index == "PointA" then
_linePoints.A.From = value
_linePoints.B.To = value
elseif index == "PointB" then
_linePoints.B.From = value
_linePoints.C.To = value
elseif index == "PointC" then
_linePoints.C.From = value
_linePoints.A.To = value
elseif (index == "Thickness" or index == "Visible" or index == "Color" or index == "ZIndex") then
for _, linePoint in _linePoints do
linePoint[index] = value
end
elseif index == "Filled" then
_linePoints.BackgroundTransparency = 1
end
triangleObj[index] = value
end,
__index = function(self, index)
if index == "Remove" or index == "Destroy" then
return function()
for _, linePoint in _linePoints do
linePoint:Remove()
end
triangleObj.Remove(self)
return triangleObj:Remove()
end
end
return triangleObj[index]
end
})
end
end
if not getgenv then
getfenv().getgenv = function() return getfenv(3) or getfenv(2) end
end
local isrenderobj = function(obj)
local s, r = pcall(function()
return obj.__type == "Drawing Object"
end)
return s and r
end
getgenv().isrenderobj = isrenderobj
getgenv().cleardrawcache = function()
drawingUI:ClearAllChildren()
end
getgenv().getrenderproperty = function(obj, prop)
assert(isrenderobj(obj), "Object must be a Drawing", 3)
return obj[prop]
end
getgenv().setrenderproperty = function(obj, prop, val)
assert(isrenderobj(obj), "Object must be a Drawing", 3)
obj[prop] = val
end
getgenv().Drawing = DrawingLib
end
function ESP:WorldToScreen(worldPosition)
local camera = workspace.CurrentCamera;
if not camera then
return nil
end;
local vector, onScreen = camera:WorldToViewportPoint(worldPosition)
if onScreen and vector.Z > 0 then
return Vector2.new(vector.X, vector.Y), vector.Z
end;
return nil, nil
end;
function ESP:GetPartBoxSize(part)
if not part then return 2, 2 end
local camera = workspace.CurrentCamera
if not camera then return 2, 2 end
local partPosition
if part:IsA("BasePart") then
partPosition = part.Position
elseif part:IsA("Model") then
partPosition = part:GetPivot().Position
else
return 2, 2
end
local distance = (camera.CFrame.Position - partPosition).Magnitude
if distance <= 0 then return 2, 2 end
local height = (camera.ViewportSize.Y / distance) * (6 / math.tan(math.rad(camera.FieldOfView * 0.5)))
return height * 0.4, height
end
function ESP:_CreateDrawingObject(type, properties)
local obj = Drawing.new(type)
for k, v in pairs(properties) do
obj[k] = v
end;
obj.Visible = true;
obj.ZIndex = self.Config.ZIndex;
table.insert(self._drawingObjects, obj)
return obj
end;
function ESP:_UpdateDrawingObject(obj, properties)
for k, v in pairs(properties) do
obj[k] = v
end
end;
function ESP:_ClearDrawingObjects()
for _, obj in ipairs(self._drawingObjects) do
obj:Remove()
end;
self._drawingObjects = {}
end;
function ESP:DrawBox(part, screenPos, boxWidth, boxHeight)
if not self.Config.ShowBoxes then
return
end;
local topLeft = Vector2.new(screenPos.X - (boxWidth / 2), screenPos.Y - boxHeight)
local boxColor = self.Config.BoxColor;
self:_CreateDrawingObject("Square", {
Position = topLeft,
Size = Vector2.new(boxWidth, boxHeight),
Color = boxColor,
Transparency = 0,
Thickness = self.Config.BoxThickness,
Filled = false
})
local accentSize = math.min(10, boxWidth * 0.2)
local accentColor = Color3.new(1, 1, 1)
self:_CreateDrawingObject("Line", {
From = topLeft,
To = Vector2.new(topLeft.X + accentSize, topLeft.Y),
Color = accentColor,
Transparency = 0.2,
Thickness = 2
})
self:_CreateDrawingObject("Line", {
From = topLeft,
To = Vector2.new(topLeft.X, topLeft.Y + accentSize),
Color = accentColor,
Transparency = 0.2,
Thickness = 2
})
local topRight = Vector2.new(topLeft.X + boxWidth, topLeft.Y)
self:_CreateDrawingObject("Line", {
From = Vector2.new(topRight.X - accentSize, topRight.Y),
To = topRight,
Color = accentColor,
Transparency = 0.2,
Thickness = 2
})
self:_CreateDrawingObject("Line", {
From = topRight,
To = Vector2.new(topRight.X, topRight.Y + accentSize),
Color = accentColor,
Transparency = 0.2,
Thickness = 2
})
local bottomLeft = Vector2.new(topLeft.X, topLeft.Y + boxHeight)
self:_CreateDrawingObject("Line", {
From = bottomLeft,
To = Vector2.new(bottomLeft.X + accentSize, bottomLeft.Y),
Color = accentColor,
Transparency = 0.2,
Thickness = 2
})
self:_CreateDrawingObject("Line", {
From = bottomLeft,
To = Vector2.new(bottomLeft.X, bottomLeft.Y - accentSize),
Color = accentColor,
Transparency = 0.2,
Thickness = 2
})
local bottomRight = Vector2.new(topLeft.X + boxWidth, topLeft.Y + boxHeight)
self:_CreateDrawingObject("Line", {
From = Vector2.new(bottomRight.X - accentSize, bottomRight.Y),
To = bottomRight,
Color = accentColor,
Transparency = 0.2,
Thickness = 2
})
self:_CreateDrawingObject("Line", {
From = bottomRight,
To = Vector2.new(bottomRight.X, bottomRight.Y - accentSize),
Color = accentColor,
Transparency = 0.2,
Thickness = 2
})
end;
function ESP:_UpdateCache()
local currentTime = tick()
if currentTime - self._cache.lastUpdate < self._cache.updateInterval then
return
end;
self._cache.lastUpdate = currentTime;
self._cache.parts = {}
if self.Callbacks.getPartsToRenderCallback then
local parts = self.Callbacks.getPartsToRenderCallback()
if parts then
for i, part in ipairs(parts) do
self._cache.parts[#self._cache.parts + 1] = part;
end
end
end
end;
function ESP:_OnRender()
if not self.Config.Enabled then
return
end;
self:_ClearDrawingObjects()
self:_UpdateCache()
for _, part in ipairs(self._cache.parts) do
if part and part.Parent then
local partPosition
if part:IsA("BasePart") then
partPosition = part.Position
elseif part:IsA("Model") then
partPosition = part:GetPivot().Position
end
local screenPos = self:WorldToScreen(partPosition)
if screenPos then
local w, h = self:GetPartBoxSize(part)
self:DrawBox(part, screenPos, w, h)
end
end
end;
for _, obj in ipairs(self._activeObjects) do
if obj.type == "circle" and obj.position then
local screenPos = self:WorldToScreen(obj.position)
if screenPos then
self:_CreateDrawingObject("Circle", {
Position = screenPos,
Radius = obj.radius,
Color = obj.color,
Transparency = obj.transparency or 0,
Thickness = obj.thickness or 2,
Filled = obj.filled or false,
NumSides = 32
})
end
elseif obj.type == "line" and obj.from and obj.to then
local fromScreen = self:WorldToScreen(obj.from)
local toScreen = self:WorldToScreen(obj.to)
if fromScreen and toScreen then
self:_CreateDrawingObject("Line", {
From = fromScreen,
To = toScreen,
Color = obj.color,
Transparency = obj.transparency or 0,
Thickness = obj.thickness or 1
})
end
end
end
end;
function ESP:SetGetPartsToRenderCallback(callback)
self.Callbacks.getPartsToRenderCallback = callback
end;
function ESP:AddObject(object)
self._activeObjects[#self._activeObjects + 1] = object;
return object
end;
function ESP:RemoveObject(object)
for i, obj in ipairs(self._activeObjects) do
if obj == object then
table.remove(self._activeObjects, i)
break
end
end
end;
function ESP:ClearObjects()
self._activeObjects = {}
end;
function ESP:SetConfig(newConfig)
for k, v in pairs(newConfig) do
self.Config[k] = v
end
end;
function ESP:Toggle()
self.Config.Enabled = not self.Config.Enabled;
return self.Config.Enabled
end;
function ESP:Init()
if self._renderConnection then
self:_Cleanup()
end;
self._renderConnection = game:GetService("RunService").RenderStepped:Connect(function()
self:_OnRender()
end)
end;
function ESP:_Cleanup()
if self._renderConnection then
self._renderConnection:Disconnect()
self._renderConnection = nil
end;
self:_ClearDrawingObjects()
end;
function ESP:Destroy()
self:_Cleanup()
self._activeObjects = {}
self:ClearCallbacks()
self._cache = {
parts = {},
lastUpdate = 0,
updateInterval = 0.1
}
end;
function ESP:ForceUpdate()
self._cache.lastUpdate = 0;
self:_UpdateCache()
end;
end
local Config = {
Enabled = true,
ShowNames = false,
ShowBoxes = true,
ShowTools = false,
BoxThickness = 2,
NameFont = 1,
FontSize = 14,
NameColor = Color3.new(1, 0, 0),
BoxColor = Color3.new(1, 0, 0),
ToolIconSize = 16,
ZIndex = 2,
}
ESP:SetConfig(Config)
local insert = function(t, v)
t[#t+1]=v
end
ESP:SetGetPartsToRenderCallback(function()
local Parts, Enemies = {}, GetEnemyTargets()
for _, Enemy in Enemies do
if Enemy.Character and Enemy.Character.Hitbox and Enemy.Character.Hitbox.Head then
insert(Parts, Enemy.Character)
end
end
return Parts
end)
ESP:Init()Review the source before using it. Executions count successful copies, capped at 10 per user and network per script in 24 hours.
Community discussion
0Start the conversation.


Your community, in one place