Changing the Clock Time Dependent to Player Map Region

Hello,

I am creating a system where ‘ClockTime’ in Lighting changes depending on what region of the map that a player is in. Ex: If a player enters a canyon area, the ClockTime would get set to 0 for that player, making it night time. If they enter a grassy area, the ClockTime gets set to 9.5, making it day time.

Here is my code so far:

local Player = game.Players.LocalPlayer
local Lighting = game.Lighting
local HitboxPart = workspace.ChaosCanyonSkyHitbox

local Found = false

if HitboxPart:FindFirstAncestor(Player.Name) then
	Found = true
else
	Found = false
end

if Found == true then
	Lighting.ClockTime = 0
elseif Found == false then
	Lighting.ClockTime = 9.5
end

I tested this and nothing happened when I entered / touched the ChaosCanyonSkyHitbox

Help would be appreciated!

1 Like

Nevermind, I figured it out, sorry

As it stands now, your code runs once then stops. It doesn’t connect any functions or do anything on a loop, which would be necessary in order to detect the player moving between zones. You can use something simple like this:

while true do
    updateClockTime() -- Write this function yourself
    wait(10) -- How often should it check?
end

Or use an event like RunService.Stepped.

Furthermore, you might have a fundamental misunderstanding of FindFirstAncestor - this function uses the hierarchy of the place as it shows in the explorer. It does not perform any bounds-checking. For that, you probably want to use a simple function like this:

local function isPointInPart(point, part)
    point = part.CFrame:PointToObjectSpace(point)
    return (point.X < part.Size.X / 2) and (point.X > part.Size.X / -2)
       and (point.Y < part.Size.Y / 2) and (point.Y > part.Size.Y / -2)
       and (point.Z < part.Size.Z / 2) and (point.Z > part.Size.Z / -2)
end

A more advanced bounds-checking solution might involve spatial query functions, but that is probably needlessly complex.

You should always post your own solution if you figure it out yourself when you asking in help forums. Someone might have your same question and find your post with no answer.

1 Like

Alright, I will post the solution

Turns out, I was doing this the wrong way. But I fixed it, if anyone else has this problem here is what I did to fix it:

I created a Folder inside of workspace called SkyRegionsGlobal and inserted a Hitbox part that covers the entirety of one map region into that folder.

Then, in a client script inside StarterGui, I wrote this code:

local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local SkyRegionsGlobal = workspace:WaitForChild("SkyRegionsGlobal")
local Found = false

while wait(1) do
	for i, v in pairs(SkyRegionsGlobal:GetChildren()) do
		Found = false

		local Region = Region3.new(v.Position - (v.Size / 2), v.Position + (v.Size / 2))
		local Parts = workspace:FindPartsInRegion3WithWhiteList(Region, Character:GetDescendants())

		for _, part in pairs(Parts) do
			if part:FindFirstAncestor(Player.Name) then
				Found = true
				break
			else
				Found = false
			end
		end

		if Found == true then
			if game.Lighting.ClockTime ~= 0 then
				game.Lighting.ClockTime = 0
				break
			end
		else
			game.Lighting.ClockTime = 9.5
		end
	end
end

The previous code I had written only ran once, but as this is in a while loop it will run infinitely.
I hope this helps anyone who has the same problem.

Shouldn’t you technically be using less than and equal to/more than and equal to? It essentially makes no difference but from a logic perspective those equals would represent the edge pixels of the BasePart instance.