Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

Is it possible to make it night in only one place of the map?

I'm making a town, and i'd like one side of the town to be night, and the other, day. I do not mean a Day/Night cycle. If that is possible, then i'd like to know how. All help is appreciated, thank you in advance.

1 comment

0

Magnitude or just parts... make sure when the part is touched the day changes, otherwise if you want a smoother look, just whip up some math and use magnitude..

3 answers

Hey, I believe the best way to do what you're trying to achieve is to use something called a Region3 value and the function game:FindPartsInRegion3WithIgnoreList. We can detect if a player is in this region in space to make sure that they are in the area you want. I'll use a Part named "Part" this example, and made it invisible (Transparency = 1). This part covers the area I WANT to cover. (Make sure you Part's CanCollide property is set to false and the Part's Size is big enough to cover the entire area you want to cover. i.e; half of the town) We can calculate the Region3 value as seen in the following code block.

local Players, ReplicatedStorage, Stepped = game:GetService("Players"), game:GetService("ReplicatedStorage"), game:GetService("RunService").Stepped;
local Part = workspace:WaitForChild("Part");
-- Size Dimensions = <80, 40, 80>
local Size, Position = Part.Size, Part.Position;

local Region = Region3.new(Position-Size/2, Position+Size/2);
--[[
Region3.new() requires 2 vectors, and using those two vectors, creates a "box". In the example above, I use one of the bottom corners and one of the top corners to create a region approx. the size of the part.
]]--

local PlayersInRegion = {};

As you may have noticed, I also create a table named PlayersInRegion to keep track of who's in the region and who isn't. Now, we need to create a loop that checks for us who and who isn't in the region (specifically every step).

while Stepped:Wait() do
	local Reg = game:FindPartsInRegion3WithIgnoreList(Region, {Part}, math.huge);
	-- Reg is essentially an array with all the parts that are in that region, excluding that part that we have in the workspace
	 for _, obj in pairs(Reg) do
		local Player = Players:GetPlayerFromCharacter(obj.Parent);
		if Player and not PlayersInRegion[Player] then
			PlayersInRegion[Player] = "checked";
			ReplicatedStorage.change:FireClient(Player, 22);
		elseif Player and PlayersInRegion[Player] then
			PlayersInRegion[Player] = "checked"
		end
	end
	for Player, _ in pairs(PlayersInRegion) do
		if PlayersInRegion[Player] ~= "checked" then
			ReplicatedStorage.change:FireClient(Player, 15.5)
			PlayersInRegion[Player] = nil
		else
			PlayersInRegion[Player] = true
		end
   	end
end

So, you may be asking, what is happening in the two for loops? Basically, we first loop through the array (Reg) of items that are in the region (excluding the part; we add in an ignore list that ignores the part). Then we check if the object in each index is a Player AND has not previously been recorded in the PlayersInRegion table because this means the player has entered the area we want to cover. I use a RemoteEvent under ReplicatedStorage and Fire what ClockTime we want a Client to be in. I'll explain this later. If we don't find the player, we can still use this loop for another aspect, whenever a player leaves the Region. If we find a player that is in the Region that has been here before, we set their table value as "checked".

In the second loop, we check which players are not "checked", meaning they aren't in the area anymore. We then fire the other time we want to the client and set their value to nil (because they aren't in the area anymore). However, if they are checked, we simply set it back to true to repeat this entire process.

Now, I fired data to the client, meaning we need to set up a LocalScript as well.

-- LocalScript
local ReplicatedStorage, Lighting, TweenService = game:GetService("ReplicatedStorage"), game:GetService("Lighting"), game:GetService("TweenService")

ReplicatedStorage.change.OnClientEvent:Connect(function(ct)
	
end)

We set up a Connection to receive client-side calls from the RemoteEvent called "changed". As you can see, I have defined some variables: ReplicatedStorage, Lighting (where you change the time), and TweenService (to smoothly change the time). The ct parameter in the Event is simply the ClockTime property of Lighting that we will change the time to. If you don't know what ClockTime is please see this. Anyways, we will cleanly Tween the day so that it doesn't look forced.

local ReplicatedStorage, Lighting, TweenService = game:GetService("ReplicatedStorage"), game:GetService("Lighting"), game:GetService("TweenService")

ReplicatedStorage.change.OnClientEvent:Connect(function(ct)
	ct = tonumber(ct) or Lighting.ClockTime -- I do this as a sanity check, not necessary
	TweenService:Create(Lighting, TweenInfo.new(1), {ClockTime = ct}):Play()
end)

Now you will have a smooth and efficient way of changing the Time in different areas. Here's the full code:


--  SERVER SCRIPT

local Players, ReplicatedStorage, Stepped = game:GetService("Players"), game:GetService("ReplicatedStorage"), game:GetService("RunService").Stepped;
local Part = workspace:WaitForChild("Part"); -- put your part here 
-- Size Dimensions = <80, 40, 80>
local Size, Position = Part.Size, Part.Position;

local Region = Region3.new(Position-Size/2, Position+Size/2);
--[[
Region3.new() requires 2 vectors, and using those two vectors, creates a "box". In the example above, I use one of the bottom corners and one of the top corners to create a region approx. the size of the part.
]]--

local PlayersInRegion = {};

while Stepped:Wait() do
	local Reg = game:FindPartsInRegion3WithIgnoreList(Region, {Part}, math.huge);
	-- Reg is essentially an array with all the parts that are in that region, excluding that part that we have in the workspace
	 for _, obj in pairs(Reg) do
		local Player = Players:GetPlayerFromCharacter(obj.Parent);
		if Player and not PlayersInRegion[Player] then
			PlayersInRegion[Player] = "checked";
			ReplicatedStorage.change:FireClient(Player, 22); -- change this with your RemoteEvent
		elseif Player and PlayersInRegion[Player] then
			PlayersInRegion[Player] = "checked"
		end
	end
	for Player, _ in pairs(PlayersInRegion) do
		if PlayersInRegion[Player] ~= "checked" then
			ReplicatedStorage.change:FireClient(Player, 15.5)
			PlayersInRegion[Player] = nil
		else
			PlayersInRegion[Player] = true
		end
   	end
end


-- LOCAL SCRIPT

local ReplicatedStorage, Lighting, TweenService = game:GetService("ReplicatedStorage"), game:GetService("Lighting"), game:GetService("TweenService")

ReplicatedStorage.change.OnClientEvent:Connect(function(ct) -- change this with your remote event
	ct = tonumber(ct) or Lighting.ClockTime -- I do this as a sanity check, not necessary
	TweenService:Create(Lighting, TweenInfo.new(1), {ClockTime = ct}):Play()
end)

--[[
WHAT YOU NEED
A RemoteEvent
A Part or Two Vector3 Values
]]--

Happy Coding :)

3 comments

0

Where do i put the localscript?

0

And the server script should be a script in the workspace or?

0

Can you be more specific?

yes, but its not exactly that you can make one place night time.. instead, you make it so when a player goes to a place, some code on client side (in a localscript) runs to make it night for only that player, and when they leave the place, you make it day time again..

1 comment

0

ty for the answer, this is write but pls include code.

I'm not sure if you can make the world half day and half night. But for players, you can locally change the daytime specifically for them to whatever you want.

This discussion is preserved as it was. New answers, comments, and votes are closed.