Paste this script into StarterPlayerScripts. It will change the color of the player’s head to red anytime they are in shadow. It does this by casting a ray from the player’s head to the sun. If it hits anything in between, then the player is in a shadow, and it does the transformation. Replace it with your monsterizing code.
local Players = game:GetService("Players")
-- Code snipped from https://create.roblox.com/docs/reference/engine/classes/Lighting#GeographicLatitude
local Lighting = game:GetService("Lighting")
local UNIT_Z = Vector3.new(0, 0, 1)
local EARTH_TILT = math.rad(23.5) -- The Earth's tilt in radians.
local HALF_SOLAR_YEAR = 182.6282 -- Half the length of an average solar year
local function getSunDirection()
local gameTime = Lighting:GetMinutesAfterMidnight()
local geoLatitude = Lighting.GeographicLatitude
local dayTime = gameTime / 1440
local sourceAngle = 2 * math.pi * dayTime
local sunPosition = Vector3.new(math.sin(sourceAngle), -math.cos(sourceAngle), 0)
local latRad = math.rad(geoLatitude)
local sunOffset = -EARTH_TILT * math.cos(math.pi * (dayTime - HALF_SOLAR_YEAR) / HALF_SOLAR_YEAR) - latRad
local sunRotation = CFrame.fromAxisAngle(UNIT_Z:Cross(sunPosition), sunOffset)
local sunDirection = sunRotation * sunPosition
return sunDirection
end
-- Loop to detect when in shadows
local oldHeadColor = nil
while true do
local character = Players.LocalPlayer.Character
if character and character:FindFirstChild("Head") then
local hit = workspace:Raycast(character.Head.CFrame.Position, getSunDirection() * 1000)
if hit then
if not oldHeadColor then
oldHeadColor = character.Head.Color
character.Head.Color = Color3.new(1, 0, 0)
end
elseif not hit and oldHeadColor then
character.Head.Color = oldHeadColor
oldHeadColor = nil
end
end
task.wait(0.25)
end
local Players = game:GetService("Players")
-- Code snipped from https://create.roblox.com/docs/reference/engine/classes/Lighting#GeographicLatitude
local Lighting = game:GetService("Lighting")
local UNIT_Z = Vector3.new(0, 0, 1)
local EARTH_TILT = math.rad(23.5) -- The Earth's tilt in radians.
local HALF_SOLAR_YEAR = 182.6282 -- Half the length of an average solar year
local function getSunDirection()
local gameTime = Lighting:GetMinutesAfterMidnight()
local geoLatitude = Lighting.GeographicLatitude
local dayTime = gameTime / 1440
local sourceAngle = 2 * math.pi * dayTime
local sunPosition = Vector3.new(math.sin(sourceAngle), -math.cos(sourceAngle), 0)
local latRad = math.rad(geoLatitude)
local sunOffset = -EARTH_TILT * math.cos(math.pi * (dayTime - HALF_SOLAR_YEAR) / HALF_SOLAR_YEAR) - latRad
local sunRotation = CFrame.fromAxisAngle(UNIT_Z:Cross(sunPosition), sunOffset)
local sunDirection = sunRotation * sunPosition
return sunDirection
end
local origHeadColor = nil
-- Loop to detect when in shadows
while true do
local character = Players.LocalPlayer.Character
if character and character:FindFirstChild("Head") then
if not origHeadColor then
origHeadColor = character.Head.Color
end
local hit = workspace:Raycast(character.Head.CFrame.Position, getSunDirection() * 1000)
if hit then
-- In shadow
character.Head.Color = origHeadColor
else
-- In sunlight
character.Head.Color = Color3.new(1, 0, 0)
end
end
task.wait(0.25)
end
Hey, I implemented this script into my game. Basically, when the player is in the sun and they have the vampire class they will slowly take damage. But during night time in certain areas the player will randomly die. Any ideas on why this is happening?
I ran the clock on a 24-hour loop and didn’t see any strange behavior with the script. At night, the sun will drift below the player’s feet, but near dusk and dawn the angle will be very shallow, like out toward the horizon. So, if the player is up on a bridge or ledge at night, and it’s just turned night, or is about to turn morning, it’s possible the ray that is cast (only 1,000 units long) will not hit anything, or it will fly off the edge of the map into the void and not hit anything. In either case, it will be assumed that the player is not in shadow because nothing is between it and the sun, therefore the player would be taking damage.
Rather than mess with these edge cases, the simple fix is to disable the check at night and re-enable in the morning.