I tried to find a script to steal utilize in one of my games that would detect if the player is in a light source or not, well I didn’t find any good ones, so I made my own. It’s not perfect but it works for me and it might work for you, attached are the script, which is in StarterCharacterScripts and a demo video
(that link expires in a week so if it doesn’t work you know why)
local LLT = 0.1 -- Set this to 0 if you want it to detect all light even if its very faint
local RS = game:GetService("RunService")
local player = game.Players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local RP = char:WaitForChild("HumanoidRootPart")
local Lights = {}
local rayParams = RaycastParams.new()
rayParams.FilterType = Enum.RaycastFilterType.Exclude
rayParams.FilterDescendantsInstances = {char}
for i, v in pairs(workspace:GetDescendants()) do
if v:IsA("SpotLight") or v:IsA("PointLight") then
table.insert(Lights, v)
end
end
function getRangeBrightnessWeight(range, brighteness)
local value = brighteness/range
return value > LLT
end
function LineOfSight(target)
local rayDirection = target.Position - RP.Position
local RayResult = workspace:Raycast(RP.Position, rayDirection, rayParams)
return RayResult.Instance == target
end
function getPointLightIlluminated(light)
if not light or not light.Parent or not light:IsA("PointLight") then
return false
end
if LineOfSight(light.Parent) then
local distanceFromPointLight = (light.Parent.Position - RP.Position).Magnitude
if not getRangeBrightnessWeight(distanceFromPointLight, light.Brightness) then return false end
if distanceFromPointLight <= light.Range - light.Range/20 then
return true
end
end
return false
end
function getAllSpotLight(target)
for i, playerPart in pairs(char:GetDescendants()) do
if playerPart:IsA("Part") or playerPart:IsA("MeshPart") then
local partToRP = (playerPart.Position - target.Parent.Position).Unit
local partLook = target.Parent.CFrame.LookVector
local dotProduct = partToRP:Dot(partLook)
local lightAngleRad = math.rad(target.Angle / 2)
local minDotProduct = math.cos(lightAngleRad)
if not getRangeBrightnessWeight((target.Parent.Position - RP.Position).Magnitude, target.Brightness) then continue end
if dotProduct > minDotProduct then
return true
end
end
end
return false
end
function getSpotLightIlluminated(light)
if not light or not light.Parent or not light:IsA("SpotLight") then
return false
end
if not LineOfSight(light.Parent, RP.Position) then
return false
end
local distanceFromPointLight = (light.Parent.Position - RP.Position).Magnitude
if distanceFromPointLight > light.Range then
return false
end
return getAllSpotLight(light)
end
game["Run Service"].Heartbeat:Connect(function()
local illuminated = false
for i, light in pairs(Lights) do
if light:IsA("PointLight") then
if getPointLightIlluminated(light) then
illuminated = true
end
elseif light:IsA("SpotLight") then
if getSpotLightIlluminated(light) then
illuminated = true
end
end
end
if illuminated == true then
char.Head.BrickColor = BrickColor.new("Sea green")
else
char.Head.BrickColor = BrickColor.new("Really red")
end
end)