In the previous tutorial we learned how to add a script to a game so we could run code when the game starts. In this tutorial, we will add a script to a game that will cycle the time of day in the game using loops and a streetlight that turns on and off at the appropriate times using conditionals.
By default Roblox does not have a day/night cycle, but we can add one ourselves with a script. First, lets look at how to change the time of day. We will use a function called SetMinutesAfterMidnight:
game.Lighting:SetMinutesAfterMidnight(5 * 60)
Functions, as mentioned in earlier tutorials, are special instructions we can use in code. print is a function we have been using quite often. print is a global function, meaning we can call it whenever we like. Other functions, such as SetMinutesAfterMidnight, are associated with specific types of instances, in this case Lighting. This means if we want to use the function, we have to specify which instance we want to use the function with. This is done similarly to how we change a property of an instance. The only difference is that we separate an instance and a function with at colon : instead of a dot ..
SetMinutesAfterMidnight is pretty straightforward as far as functions go. We simply put a number between the two parenthesis after the number to indicate how many minutes after midnight we want to set the world to. The above code would set the time to 5AM (as 5 times 60 minutes is 5 hours).
We can change the time of day several times in a row:
game.Lighting:SetMinutesAfterMidnight(5 * 60) game.Lighting:SetMinutesAfterMidnight(6 * 60) game.Lighting:SetMinutesAfterMidnight(7 * 60) game.Lighting:SetMinutesAfterMidnight(8 * 60) game.Lighting:SetMinutesAfterMidnight(9 * 60)
The above code changes the time from 5AM, then 6AM, then 7AM, and so on. But there is a problem. If we run the game right now, the time will instantly change to 9AM. Why does this happen? Why didn't we see the other changes?
It turns out that the game did change the time of day several times as we instructed, it just did it so fast we couldn't see. When a game runs a script, it runs it as fast as it can. Most instructions will only take a mere fraction of a second, far too quick for us to notice. In order to see the changes take place over a time span we can actually see, we need to make the script pause between each change. To do that, we will use a global function called wait:
game.Lighting:SetMinutesAfterMidnight(5 * 60) wait(1) game.Lighting:SetMinutesAfterMidnight(6 * 60) wait(1) game.Lighting:SetMinutesAfterMidnight(7 * 60) wait(1) game.Lighting:SetMinutesAfterMidnight(8 * 60) wait(1) game.Lighting:SetMinutesAfterMidnight(9 * 60)
Whenever we call wait in a script, we are giving the script the instruction to pause for the amount of time we specified (in seconds). In the above code, the script will pause for one second between each time change, which gives us enough time to notice the day progressing.
The above code work fine over a very short period of time, but what if we wanted the time of day to keep changing for minutes? Hours? We would need to write thousands of lines of code. There is fortunately a very simple alternative that we can use to avoid this called looping.
A loop is a segment of code that repeats itself over and over until a certain condition is met; Some loops can even run indefinitely until the game stops. One loop that can loop indefinitely is a while loop. Take a look at the following example:
number = 0 while true do number = number + 1 print(number) wait(1) end
The first line of the script simply makes a variable called number and stores the value 0 in it. The second line sets up a loop: while is the type of loop and true is the condition for the loop to repeat. Since we don't want the loop to ever end, we can just say true here and the loop will continue forever (we will go over stopping a loop in a future tutorial). The code in between do and end is all the code we want to repeat. In this case, 1 will be added to the value inside of number, and that sum will be stored back into number. We then print out number and tell the script to wait for one second. After that, the loop will repeat itself starting with adding 1 to number.
Let's see how we can use a loop like above to cycle the day and night.
minutesAfterMidnight = 0 while true do minutesAfterMidnight = minutesAfterMidnight + 1 game.Lighting:SetMinutesAfterMidnight(minutesAfterMidnight) wait(.1) end
In this code we keep track of the time with the variable minutesAfterMidnight. In every cycle of the loop we increase the value in minutesAfterMidnight by 1 and then update the time using SetMinutesAfterMidnight. We then wait 1/10th of a second to make the script pause before repeating the loop. If you let the game run for a bit now you will see the day gradually change from night to day.
Let's add a streetlight to our game. This light will turn on at night and off during the day. First construct the light:
Make sure the part we want to illuminate is named LightPart. This part should have the neon material so it appears to glow. Also insert a PointLight into the part so that it emits light on the parts around it. Feel free to play with the Color, Brightness, and Range of the PointLight so it creates the effect you want.
Now, let's modify our script above to turn off the light during the day. Specifically, we will turn the light off at 6AM. We will also speed up the time of day cycle so we can quickly test the code.
lightPart = game.Workspace.LightPart minutesAfterMidnight = 0 while true do minutesAfterMidnight = minutesAfterMidnight + 10 game.Lighting:SetMinutesAfterMidnight(minutesAfterMidnight) if game.Lighting:GetMinutesAfterMidnight() == 6 * 60 then lightPart.Material = Enum.Material.Plastic lightPart.PointLight.Enabled = false end wait(0.1) end
We start by making a variable for the LightPart. In our loop we add something called an if statement. An if statement runs code only if a certain condition has been met. In this case, we want to check it the time of day is 6AM. To check if two things are equal in Lua, we use two equal signs ==. The code between then and else will run only if the number of minutes after midnight is exactly the same as 6 * 60 (= 6 hours). If we run the code now we will see the light will become plastic and the PointLight inside will stop shining.
To turn the light on again at the end of the day, we can simply follow up with another if statement:
lightPart = game.Workspace.LightPart minutesAfterMidnight = 0 while true do minutesAfterMidnight = minutesAfterMidnight + 10 game.Lighting:SetMinutesAfterMidnight(minutesAfterMidnight) wait(0.1) if game.Lighting:GetMinutesAfterMidnight() == 6 * 60 then -- checks for 6AM lightPart.Material = Enum.Material.Plastic lightPart.PointLight.Enabled = false end if game.Lighting:GetMinutesAfterMidnight() == 18 * 60 then -- checks for 6PM lightPart.Material = Enum.Material.Neon lightPart.PointLight.Enabled = true end end
Our game can now cycle through the day and night, and we have a light that automatically turns itself on and off! In the next tutorial we will cover how to use events to light parts on fire and then douse them.