Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

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

Asked by 4 years ago

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.

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.. greatneil80 2647 — 4y

3 answers

Log in to vote
1
Answered by 4 years ago
Edited 4 years ago

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 :)

0
Where do i put the localscript? TheJacksterYT 19 — 4y
0
And the server script should be a script in the workspace or? TheJacksterYT 19 — 4y
0
Can you be more specific? TheJacksterYT 19 — 4y
Ad
Log in to vote
0
Answered by 4 years ago

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..

0
ty for the answer, this is write but pls include code. royaltoe 5144 — 4y
Log in to vote
0
Answered by 4 years ago

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.

Answer this question