I’ve been continuing work on a game of mine, and recently I have created a graveyard. To add extra effects, I’d like it so that while the player is in the graveyard, the time appears as night. Unfortunately, I haven’t been able to get it to work properly. Here’s my code:
local Part = script.Parent
Part.Touched:Connect(function()
game:GetService("Lighting"):SetMinutesAfterMidnight(0)
end)
There are two issues:
This function doesn’t work in a localscript, meaning the time changes for everyone.
This script permanently changes the time, not temporarily changes it only while the player touches it.
Is there any way to achieve this? I understand that this question might be out of the scope of the Roblox engine, but I thought I’d ask the magical devforum!
Only way I can think of emulating (gotta make it bold so I can emphasize it) is making a slightly transparent frame that is black / silver (which makes it appear like it’s night time I guess).
There are a couple ways you could go about doing this. One would to use a remote event (server to client), another would to have a script in StarterPlayerScripts that gets the part from workspace and detects when its touched.
If you specifically want the script to be inside the part, you could place a normal script in it and set the run context to client.
local Part = script.Parent
local Lighting = game:GetService("Lighting")
Part.Touched:Connect(function()
Lighting.ClockTime = 0 -- set the time to 0, making it night
end)
local Part = workspace.Part
Part.Touched:Connect(function(hit)
if hit.Parent:FindFirstChild("Humanoid") then
game:GetService("Lighting"):SetMinutesAfterMidnight(0)
end
end)
Part.TouchEnded:Connect(function()
if hit.Parent:FindFirstChild("Humanoid") then
game:GetService("Lighting"):SetMinutesAfterMidnight(720)
end
end)
local tSpawn = task.spawn
local tWait = task.wait
local find = table.find
local LTG = game:GetService("Lighting")
local player = game:GetService('Players').LocalPlayer
local Part = workspace.Part
local touching: boolean = false
Part.Touched:Connect(function(hit)
if touching then return end
local char: Model? = hit.Parent
if player.Character == char then
touching = true
tSpawn(function()
while touching do
local partTouched = false
tWait(0.1)
for _, child in ipairs(char:GetChildren()) do
if find(Part:GetTouchingParts(), child) then
partTouched = true
LTG.ClockTime = 0 -- night
end
end
touching = partTouched
end
LTG.ClockTime = 12 -- noon
end)
end
end)
Something I recommend is rather than checking whether the character is touching, you can check for is distance using (Part.Position - HumanoidRootPart.Position).Magnitude
The time change has to happen on the client.
The reason its not working on the client is because you have to set the run context of the script to be ‘client’
Also, you will need to do a Touch:Connect and Touch:Ended.
local lighting = game:GetService("Lighting")
local currentTime = lighting.ClockTime
local speed = 1 --time for the sky to change
local isDark = false --
local playerInBox = false
local hitBox = script.Parent
--hide hitbox
hitBox.Transparency = 1
--====== Tweening Things ===========
local tweenInfo = TweenInfo.new(
speed,
Enum.EasingStyle.Quart,
Enum.EasingDirection.Out,
0,
false,
0
)
local tweenDarken = game.TweenService:Create(lighting,tweenInfo,{ClockTime = 0})
local tweenBrighten = game.TweenService:Create(lighting,tweenInfo,{ClockTime = currentTime})
--============= End Tweening Things =========================
function CheckForBrighten() --this checks to see if anyone is standing in the box, if not brighten the sky
if playerInBox == false then
isDark = false
tweenBrighten:Play()
tweenBrighten.Completed:Wait()
end
end
hitBox.Touched:Connect(function(part)
local player = game.Players:GetPlayerFromCharacter(part.Parent)
if player and player.Character and player.Character.PrimaryPart == part then
playerInBox = true
if isDark == false then
tweenDarken:Play()
tweenDarken.Completed:Wait()
isDark = true
CheckForBrighten() --this is called in case players left the hitbox while the sky is darkening
end
end
end)
hitBox.TouchEnded:Connect(function(part)
local player = game.Players:GetPlayerFromCharacter(part.Parent)
if player and player.Character and player.Character.PrimaryPart == part then
playerInBox = false
if isDark == true then
CheckForBrighten() --see if the sky needs to brighten, in case player is out of hit box, and sky is fully dark
end
end
end)
This works well! The only issue is that the time changes for the whole server, not for the one player who enters the hitbox. The code also doesn’t work in a localscript either.
Is there a setting I’m missing? I set the script runcontext to client. Any help is appreciated
**Edit, I see it is doing it for all clients, however, I do know its possible to only change one client, because I have a wardrobe system, that brightens for one client, so you can see how to change your clothing even at night.
I just don’t remember how I did it, I will look into my old code later today and see what I did to get it to change only one client, and get back to you.
I included the project file, did you download it and see?
I actually managed to make it work. To help debug, I used Google’s Bard AI chatbot to help me. When I told him the issue, he replied with this script:
local lighting = game:GetService("Lighting")
local currentTime = lighting.ClockTime
local speed = 1 --time for the sky to change
local isDark = false --
local playerInBox = false
local hitBox = script.Parent
--hide hitbox
hitBox.Transparency = 1
--====== Tweening Things ===========
local tweenInfo = TweenInfo.new(
speed,
Enum.EasingStyle.Quart,
Enum.EasingDirection.Out,
0,
false,
0
)
local tweenDarken = game.TweenService:Create(lighting,tweenInfo,{ClockTime = 0})
local tweenBrighten = game.TweenService:Create(lighting,tweenInfo,{ClockTime = currentTime})
--============= End Tweening Things =========================
function CheckForBrighten() --this checks to see if anyone is standing in the box, if not brighten the sky
if playerInBox == false then
isDark = false
tweenBrighten:Play()
tweenBrighten.Completed:Wait()
end
end
hitBox.Touched:Connect(function(part)
local player = game.Players.LocalPlayer
if player and player.Character and player.Character.PrimaryPart == part then
playerInBox = true
if isDark == false then
tweenDarken:Play()
tweenDarken.Completed:Wait()
isDark = true
CheckForBrighten() --this is called in case players left the hitbox while the sky is darkening
end
end
end)
hitBox.TouchEnded:Connect(function(part)
local player = game.Players.LocalPlayer
if player and player.Character and player.Character.PrimaryPart == part then
playerInBox = false
if isDark == true then
CheckForBrighten() --see if the sky needs to brighten, in case player is out of hit box, and sky is fully dark
end
end
end)
and said that:
“The only change I made was to use the LocalPlayer variable instead of the Players variable when getting the player. This ensures that the lighting changes are only applied to the local player.”
And it works! Glad I could get it sorted. I will mark your answer as the solution