
KeylessUniversal

-- Player Vision Detection System
-- Detects when other players can see you (no walls blocking)
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local LocalPlayer = Players.LocalPlayer
-- Configuration
local FOV_ANGLE = 90 -- Field of view in degrees (half angle, so total is 180°)
local MAX_VISION_DISTANCE = 100 -- Maximum distance they can see
local SCAN_INTERVAL = 0.1 -- How often to check (seconds)
local VISUALIZE = true -- Show debug visualization
-- Convert degrees to radians
local FOV_RADIANS = math.rad(FOV_ANGLE)
-- Store players who can currently see you
local playersWhoSeeYou = {}
-- Create GUI for displaying who sees you
local function createGUI()
local screenGui = Instance.new("ScreenGui")
screenGui.Name = "VisionDetectorGUI"
screenGui.ResetOnSpawn = false
screenGui.Parent = LocalPlayer:WaitForChild("PlayerGui")
local frame = Instance.new("Frame")
frame.Size = UDim2.new(0, 250, 0, 300)
frame.Position = UDim2.new(1, -260, 0, 10)
frame.BackgroundColor3 = Color3.fromRGB(30, 30, 30)
frame.BackgroundTransparency = 0.3
frame.BorderSizePixel = 0
frame.Parent = screenGui
local corner = Instance.new("UICorner")
corner.CornerRadius = UDim.new(0, 8)
corner.Parent = frame
local title = Instance.new("TextLabel")
title.Size = UDim2.new(1, -20, 0, 30)
title.Position = UDim2.new(0, 10, 0, 5)
title.BackgroundTransparency = 1
title.Text = "Players Who See You:"
title.TextColor3 = Color3.fromRGB(255, 255, 255)
title.TextSize = 16
title.Font = Enum.Font.GothamBold
title.TextXAlignment = Enum.TextXAlignment.Left
title.Parent = frame
local listFrame = Instance.new("ScrollingFrame")
listFrame.Size = UDim2.new(1, -20, 1, -45)
listFrame.Position = UDim2.new(0, 10, 0, 40)
listFrame.BackgroundTransparency = 1
listFrame.BorderSizePixel = 0
listFrame.ScrollBarThickness = 6
listFrame.Parent = frame
local listLayout = Instance.new("UIListLayout")
listLayout.SortOrder = Enum.SortOrder.Name
listLayout.Padding = UDim.new(0, 5)
listLayout.Parent = listFrame
return listFrame
end
local listFrame = createGUI()
-- Update GUI with current players
local function updateGUI()
-- Clear existing labels
for _, child in ipairs(listFrame:GetChildren()) do
if child:IsA("TextLabel") then
child:Destroy()
end
end
-- Create labels for each player who sees you
for playerName, data in pairs(playersWhoSeeYou) do
local label = Instance.new("TextLabel")
label.Size = UDim2.new(1, 0, 0, 25)
label.BackgroundColor3 = Color3.fromRGB(200, 50, 50)
label.BackgroundTransparency = 0.5
label.Text = playerName .. " (" .. math.floor(data.distance) .. " studs)"
label.TextColor3 = Color3.fromRGB(255, 255, 255)
label.TextSize = 14
label.Font = Enum.Font.Gotham
label.Parent = listFrame
local corner = Instance.new("UICorner")
corner.CornerRadius = UDim.new(0, 4)
corner.Parent = label
end
end
-- Check if a point is within a cone
local function isInCone(observerPos, observerLookVector, targetPos, fovRadians, maxDistance)
local toTarget = targetPos - observerPos
local distance = toTarget.Magnitude
-- Check distance first
if distance > maxDistance then
return false, distance
end
-- Normalize the vector
local directionToTarget = toTarget.Unit
-- Calculate the angle between look vector and direction to target
local dotProduct = observerLookVector:Dot(directionToTarget)
local angleRadians = math.acos(math.clamp(dotProduct, -1, 1))
-- Check if within FOV
return angleRadians <= fovRadians, distance
end
-- Perform raycast to check for walls
local function hasLineOfSight(fromPos, toPos, ignoreList)
local direction = toPos - fromPos
local distance = direction.Magnitude
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = ignoreList
raycastParams.FilterType = Enum.RaycastFilterType.Exclude
raycastParams.IgnoreWater = true
local result = workspace:Raycast(fromPos, direction, raycastParams)
-- If no hit, or hit is very close to target position, line of sight is clear
if not result then
return true
end
-- Check if we hit something before reaching the target
local hitDistance = (result.Position - fromPos).Magnitude
return hitDistance >= distance - 2 -- Small tolerance
end
-- Visualize FOV cone (for debugging)
local visualParts = {}
local function visualizeCone(character, canSeeLocalPlayer)
if not VISUALIZE then return end
-- Clear old visualization for this character
local charName = character.Name
if visualParts[charName] then
for _, part in ipairs(visualParts[charName]) do
part:Destroy()
end
end
visualParts[charName] = {}
local head = character:FindFirstChild("Head")
if not head then return end
-- Create a cone visualization
local cone = Instance.new("Part")
cone.Shape = Enum.PartType.Block
cone.Size = Vector3.new(0.5, 0.5, MAX_VISION_DISTANCE / 2)
cone.CFrame = head.CFrame * CFrame.new(0, 0, -MAX_VISION_DISTANCE / 4)
cone.Color = canSeeLocalPlayer and Color3.fromRGB(255, 0, 0) or Color3.fromRGB(100, 100, 255)
cone.Transparency = 0.7
cone.CanCollide = false
cone.Anchored = true
cone.Material = Enum.Material.Neon
cone.Parent = workspace
table.insert(visualParts[charName], cone)
-- Auto-destroy after a short time
task.delay(SCAN_INTERVAL + 0.05, function()
if cone and cone.Parent then
cone:Destroy()
end
end)
end
-- Main detection function
local function checkVision()
local localChar = LocalPlayer.Character
if not localChar then return end
local localRoot = localChar:FindFirstChild("HumanoidRootPart")
local localHead = localChar:FindFirstChild("Head")
if not localRoot or not localHead then return end
local localPos = localHead.Position
-- Clear previous detections
playersWhoSeeYou = {}
-- Check each other player
for _, player in ipairs(Players:GetPlayers()) do
if player ~= LocalPlayer then
local char = player.Character
if char then
local humanoid = char:FindFirstChildOfClass("Humanoid")
local head = char:FindFirstChild("Head")
local root = char:FindFirstChild("HumanoidRootPart")
if humanoid and humanoid.Health > 0 and head and root then
-- Get the direction the player is facing
local lookVector = root.CFrame.LookVector
local observerPos = head.Position
-- Check if local player is in their FOV cone
local inCone, distance = isInCone(observerPos, lookVector, localPos, FOV_RADIANS, MAX_VISION_DISTANCE)
if inCone then
-- Check line of sight (no walls)
local ignoreList = {localChar, char}
local hasLOS = hasLineOfSight(observerPos, localPos, ignoreList)
if hasLOS then
playersWhoSeeYou[player.Name] = {
distance = distance,
player = player
}
visualizeCone(char, true)
else
visualizeCone(char, false)
end
else
visualizeCone(char, false)
end
end
end
end
end
updateGUI()
end
-- Run the detection loop
local lastScan = 0
RunService.Heartbeat:Connect(function()
local now = tick()
if now - lastScan >= SCAN_INTERVAL then
lastScan = now
checkVision()
end
end)
-- Clean up visualizations when players leave
Players.PlayerRemoving:Connect(function(player)
if visualParts[player.Name] then
for _, part in ipairs(visualParts[player.Name]) do
part:Destroy()
end
visualParts[player.Name] = nil
end
end)
print("Vision Detection System Activated!")
print("Players who can see you will appear in the top-right GUI")
print("Red cones = Can see you | Blue cones = Cannot see you")



AI
This just checks if they are facing you, not looking at you.
"I made" 💔💔
@vxsty *ai made*