local settings = { -- Visual Settings color = Color3.fromRGB(255, 255, 255), -- Crosshair color (White) thickness = 1, -- Line thickness (pixels) length = 5, -- Length of each line (pixels) gap = 2, -- Center gap (pixels) opacity = 1, -- Transparency (0-1) dot = false, -- Enable center dot dot_size = 2, -- Dot size (pixels) -- Positioning x_offset = 0, -- Horizontal adjustment y_offset = 0, -- Vertical adjustment recenter = true -- Auto-adjust on screen resize } -- Services local cam = workspace.CurrentCamera or workspace:FindFirstChildOfClass("Camera") local Players = game:GetService("Players") local Player = Players.LocalPlayer -- Crosshair objects local crosshair = { top = nil, bottom = nil, left = nil, right = nil, dot = nil, connections = {} } -- Cleanup function (prevents memory leaks) local function cleanup() for _, part in pairs(crosshair) do if typeof(part) == "Drawing" then part:Remove() elseif typeof(part) == "RBXScriptConnection" then part:Disconnect() end end crosshair = { top = nil, bottom = nil, left = nil, right = nil, dot = nil, connections = {} } end -- Create a new drawing object local function createLine() return Drawing.new("Line") end -- Initialize crosshair local function initCrosshair() cleanup() -- Create crosshair parts crosshair.top = createLine() crosshair.bottom = createLine() crosshair.left = createLine() crosshair.right = createLine() if settings.dot then crosshair.dot = Drawing.new("Circle") crosshair.dot.Thickness = 1 crosshair.dot.Filled = true crosshair.dot.Color = settings.color crosshair.dot.Transparency = settings.opacity crosshair.dot.Visible = true end -- Apply common properties for _, part in pairs({crosshair.top, crosshair.bottom, crosshair.left, crosshair.right}) do part.Thickness = settings.thickness part.Color = settings.color part.Transparency = settings.opacity part.Visible = true end -- Auto-recenter on screen resize if settings.recenter then table.insert(crosshair.connections, cam:GetPropertyChangedSignal("ViewportSize"):Connect(function() updateCrosshair() -- Refresh position on resize end)) end end -- Update crosshair position (static, no scaling) local function updateCrosshair() local centerX = (cam.ViewportSize.X / 2) + settings.x_offset local centerY = (cam.ViewportSize.Y / 2) + settings.y_offset -- Top line crosshair.top.From = Vector2.new(centerX, centerY - settings.gap) crosshair.top.To = Vector2.new(centerX, centerY - settings.gap - settings.length) -- Bottom line crosshair.bottom.From = Vector2.new(centerX, centerY + settings.gap) crosshair.bottom.To = Vector2.new(centerX, centerY + settings.gap + settings.length) -- Left line crosshair.left.From = Vector2.new(centerX - settings.gap, centerY) crosshair.left.To = Vector2.new(centerX - settings.gap - settings.length, centerY) -- Right line crosshair.right.From = Vector2.new(centerX + settings.gap, centerY) crosshair.right.To = Vector2.new(centerX + settings.gap + settings.length, centerY) -- Center dot if crosshair.dot then crosshair.dot.Position = Vector2.new(centerX, centerY) crosshair.dot.Radius = settings.dot_size end end -- Initialize initCrosshair() updateCrosshair() -- Cleanup on player leave table.insert(crosshair.connections, Player.CharacterRemoving:Connect(cleanup)) table.insert(crosshair.connections, game:BindToClose(cleanup))