-- Optimized XRay Script for Roblox (Educational Purpose)
-- Place this LocalScript in StarterPlayerScripts.
-- This script makes buildings/parts semi-transparent to see through walls
-- Press N to toggle XRay mode
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local Workspace = game:GetService("Workspace")
local LocalPlayer = Players.LocalPlayer
-- Settings
local XRayKey = Enum.KeyCode.N
local TransparencyAmount = 0.5 -- 0 = fully visible, 1 = fully transparent
local RefreshRate = 1.0 -- Increased from 0.5 to 1.0 seconds between updates
local MaxDistance = 2000 -- Restored to 2000 studs
local ExcludedNames = {"Terrain", "BasePlate"} -- Parts to exclude from XRay
local ExcludedClassNames = {"Terrain", "Sky", "Camera"} -- Exclude by class too
-- State
local xRayEnabled = false
local originalTransparency = {}
local trackedParts = {} -- Track parts we're managing
local lastUpdateTime = 0
-- Cache frequently used objects
local excludedNameLookup = {}
for _, name in ipairs(ExcludedNames) do
excludedNameLookup[name] = true
end
local excludedClassLookup = {}
for _, className in ipairs(ExcludedClassNames) do
excludedClassLookup[className] = true
end
-- Helper: check if part should be excluded
local function shouldExcludePart(part)
return excludedNameLookup[part.Name] or excludedClassLookup[part.ClassName]
end
-- Helper: more efficient part collection using spatial query
local function getVisiblePartsInRange()
local character = LocalPlayer.Character
if not character then return {} end
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
if not humanoidRootPart then return {} end
local playerPosition = humanoidRootPart.Position
local parts = {}
-- Use spatial query for maximum performance
local region = Region3.new(
playerPosition - Vector3.new(MaxDistance, MaxDistance, MaxDistance),
playerPosition + Vector3.new(MaxDistance, MaxDistance, MaxDistance)
)
local partsInRegion = Workspace:FindPartsInRegion3(region, nil, math.huge)
for _, part in ipairs(partsInRegion) do
if part:IsA("BasePart") and not shouldExcludePart(part) then
parts[part] = true
end
end
return parts
end
-- Enable XRay
local function enableXRay()
local visibleParts = getVisiblePartsInRange()
for part in pairs(visibleParts) do
if not originalTransparency[part] then
originalTransparency[part] = part.Transparency
trackedParts[part] = true
end
part.Transparency = TransparencyAmount
end
xRayEnabled = true
end
-- Disable XRay
local function disableXRay()
for part in pairs(trackedParts) do
if part.Parent then
part.Transparency = originalTransparency[part] or 0
end
end
originalTransparency = {}
trackedParts = {}
xRayEnabled = false
end
-- Toggle XRay with N key
UserInputService.InputBegan:Connect(function(input, gameProcessedEvent)
if gameProcessedEvent then return end
if input.UserInputType == Enum.UserInputType.Keyboard and input.KeyCode == XRayKey then
if xRayEnabled then
disableXRay()
else
enableXRay()
end
end
end)
-- Optimized update using Heartbeat with frame skipping
local heartbeatConnection
local updateFrameCounter = 0
local framesBetweenUpdates = math.ceil(RefreshRate * 60) -- Update every ~1 second at 60FPS
local function onHeartbeat()
if not xRayEnabled then return end
updateFrameCounter = updateFrameCounter + 1
if updateFrameCounter < framesBetweenUpdates then return end
updateFrameCounter = 0
local visibleParts = getVisiblePartsInRange()
-- Update transparency for current visible parts
for part in pairs(visibleParts) do
if not originalTransparency[part] then
originalTransparency[part] = part.Transparency
trackedParts[part] = true
end
part.Transparency = TransparencyAmount
end
-- Clean up parts that are no longer tracked
for part in pairs(trackedParts) do
if not visibleParts[part] and part.Parent then
part.Transparency = originalTransparency[part] or 0
trackedParts[part] = nil
end
if not part.Parent then
trackedParts[part] = nil
originalTransparency[part] = nil
end
end
end
-- Connect to Heartbeat for optimized updates
heartbeatConnection = RunService.Heartbeat:Connect(onHeartbeat)
-- Clean up connections
script.Destroying:Connect(function()
if heartbeatConnection then
heartbeatConnection:Disconnect()
end
if xRayEnabled then
disableXRay()
end
end) make this xray not be used on invisible and only be on parts that are visible, keep the distance and performance, NO LAG SPIKES OR LAG