This commit is contained in:
Joe 2026-02-02 12:08:47 -06:00
parent a9b4f8e83b
commit e6efc04756
8494 changed files with 495610 additions and 0 deletions

View file

@ -0,0 +1,320 @@
---
title: Loops practice - create a timed bridge
description: Make a bridge that disappears to add challenge to a Roblox experience. Combine for loops and while loops in this computer science practice.
next: /tutorials/fundamentals/coding-4/nested-loops
prev: /tutorials/fundamentals/coding-4/glow-lights-with-for-loops
---
This project is another example of using for loops in a practical way. For this bridge, players will touch a button to make a bridge walkable for a limited time before it disappears. To create a timer and show the remaining time to a player, you'll use for loops.
<video controls src="../../../assets/education/coding-4/timedBridgePresentation.mp4" width="100%"></video>
## Set up the project
This bridge can be included in any Roblox project with movement-based challenges, like an obby.
### Create parts
1. Find a place to build a bridge, like a river or a large gap in an obby. Create three **anchored** parts like below.
- TimerDisplay
- Bridge
- ButtonBridge
<img src="../../../assets/education/coding-4/forLoopBridge_bridgeSetup.png" width="100%" />
2. When inactive, the bridge will be semi-transparent. To do so, select the **Bridge** and change it's properties.
- **Transparency** = 0.8
- **CanCollide** = False
### Create the timer display
When crossing the bridge, players will need to see how many seconds are left before the bridge disappears. One way to display images or text is by adding an object called a Surface GUI to a part. **Surface GUIs** can also be used to create in-game signs, custom health bars, and inventory systems. This tutorial will go through this quickly, but more information can be found in the [Tutorials](../../../tutorials/index.md) section.
1. Select TimerDisplay and add a **SurfaceGui**. Then, parented to the Surface Gui, add a **TextLabel**.
<img src="../../../assets/education/coding-4/forLoopBridge_addTextLabel.png" />
2. Select the Surface GUI. In the Properties, make the following changes:
- Change the **Face** so you can see the text label on the front of the timer where the player is looking.
3. Select the TextLabel. In the Properties, make the following changes:
- Set **Size** to `{1, 0},{1, 0}`.
- Set **TextScaled** to true.
- Set **Text** to be blank. Text will be updated using the script.
### Set up the script
Now that the timer is in place, create a script to control the bridge and display the countdown number to players.
1. In the Bridge part, add a new script named TimedBridge. In that script, create the following variables.
```lua
local bridge = script.Parent
local button = workspace.ButtonBridge
local timerText = workspace.TimerDisplay.SurfaceGui.TextLabel
-- How long the bridge will stay solid
local timerDuration = 5
```
## Code the touch interaction
To use the bridge, you'll need to create two functions. One function will make the bridge walkable and display the timer. The other function will listen for if a player touches the button that activates the bridge.
1. Create a new function named `startTimer()` with a print statement inside. You'll use the print statement to test your code.
```lua
local timerDuration = 5
local function startTimer()
print("Countdown started")
end
```
2. Code a function named `buttonPressed()` to check if a humanoid touches the button. The function should accept a parameter of `partTouched`, and then have an empty if statement if a humanoid is detected in that part.
```lua
local function startTimer()
print("Countdown started")
end
local function buttonPressed(partTouched)
local character = partTouched.Parent
local humanoid = character:FindFirstChildWhichIsA("Humanoid")
if humanoid then
end
end
```
3. To start the timer, in the `if` statement, call the `startTimer()` function.
```lua
local function buttonPressed(otherPart)
local character = otherPart.Parent
local humanoid = character:FindFirstChildWhichIsA("Humanoid")
if humanoid then
startTimer()
end
end
```
4. Under the end of `buttonPressed()`, connect the `buttonPressed()` function to the button's `Touched` event.
```lua
local function buttonPressed(otherPart)
local character = otherPart.Parent
local humanoid = character:FindFirstChildWhichIsA("Humanoid")
if humanoid then
startTimer()
end
end
button.Touched:Connect(buttonPressed)
```
5. Run the project. Touch the part and check in the Output window to see the print statement.
### Troubleshooting tips
At this point, if the bridge doesn't work as intended, try one of the following below.
**Issue**: Error message saying: `"... is not a valid member of workspace"`.
- In the TimedBridge script, check that all parts are spelled exactly as they're seen in the Explorer.
**Issue**: Can't see the parts.
- Make sure all three parts are Anchored.
- Check the Transparency property for the bridge.
## Create the timer
Whenever players step on the bridge, `startTimer()` will make the bridge walkable and start the timer. Once the timer reaches 0, the bridge will become unwalkable, causing anyone who's not fast enough to fall.
### Make the bridge walkable
To start, the script will need to make the bridge solid, or collidable and then start a timer until it becomes unwalkable.
1. To make the bridge walkable, in `startTimer()`, change the bridge's Transparency property to 0 (opaque) and the CanCollide property to true.
```lua
local function startTimer()
-- Make the bridge visible and walkable
bridge.Transparency = 0
bridge.CanCollide = true
end
```
2. To create a timer that counts down, create a for loop with the following values.
- **Control Variable**: named `count`, set to `timerDuration`.
- **End**: 0
- **Increment**: -1
```lua
local function startTimer()
-- Make the bridge visible and walkable
bridge.Transparency = 0
bridge.CanCollide = true
for count = timerDuration, 0, -1 do
end
end
```
3. To show the timer to players, change the text in `timerText` to display count by typing `timerText.Text = count`. Each time the for loop goes through an iteration, it'll show players the next number in the timer.
```lua
for count = timerDuration, 0, -1 do
timerText.Text = count
end
```
4. Use a task.wait function to make the for loop run only once a second.
```lua
for count = timerDuration, 0, -1 do
timerText.Text = count
task.wait(1)
end
```
5. Run the experience. When you touch the button, the bridge should appear and the timer will start, then complete.
<video controls src="../../../assets/education/coding-4/forLoopBridge-finishedCountdown.mp4" width="100%"></video>
## Keep the bridge from restarting
Notice though, if you move around on the button, the timer will keep restarting.
<video controls src="../../../assets/education/coding-4/forLoop_outputError.mp4" width="100%"></video>
This is because the for loop is being called each time you touch the button and starting the for loop from the beginning. To keep the timer from constantly restarting, you'll need to add a boolean, a type of variable, that will control whether or not `startTimer()` is allowed to be called again.
**Booleans** are written the same way as other variables, but instead of using numbers or strings, they can only be set to true or false. In this situation, the script will use a boolean to check if the timer is currently running before starting it.
1. At the top of your script, under your variables, create a variable named `timerActive` and set it to `false` since nobody has pressed the button yet.
```lua
local timerDuration = 5
local timerActive = false
local function startTimer()
```
2. To makes sure the timer only starts when the `timerActive` boolean is false, add a second condition to the if statement in `buttonPressed()`.
```lua
local function buttonPressed(otherPart)
local character = otherPart.Parent
local humanoid = character:FindFirstChildWhichIsA("Humanoid")
if humanoid and timerActive == false then
startTimer()
end
end
```
3. To keep `startTimer()` from running again before the timer runs out, set the boolean `timerActive` to true.
```lua
local function startTimer()
timerActive = true
bridge.Transparency = 0
bridge.CanCollide = true
```
4. In the `startTimer()` function, **after** the for loop, set the bridge back to its original properties by changing the bridge's transparency to 0.8 and CanCollide to false.
```lua
local function startTimer()
timerActive = true
bridge.Transparency = 0
bridge.CanCollide = true
-- For loop that counts down from timerDuration
for count = timerDuration, 0, -1 do
timerText.Text = count
task.wait(1)
end
-- Make the bridge not walkable
bridge.Transparency = 0.8
bridge.CanCollide = false
end
```
5. One last thing to reset the bridge is to change the `timerText` to an empty string like how it was originally. Then, set the `timerActive` boolean to false.
```lua
bridge.Transparency = 0.8
bridge.CanCollide = false
timerText.Text = ""
timerActive = false
```
6. Playtest and check to make sure the bridge can be used multiple times.
<video controls src="../../../assets/education/coding-4/timedBridgePresentation.mp4" width="100%"></video>
## Complete timed bridge script
```lua
local bridge = script.Parent
-- Gets the button as it's typed in the Explorer
local button = workspace.ButtonBridge
-- Gets the part for the display
local timerPart = workspace.TimerDisplay
-- Gets the Text that will display the timer
local timerText = timerPart.SurfaceGui.TextLabel
-- How long players have to cross the bridge
local timerDuration = 5
local timerActive = false
local function startTimer()
print("Countdown started")
timerActive = true
bridge.Transparency = 0
bridge.CanCollide = true
-- For loop that counts down from timerDuration
for count = timerDuration, 0, -1 do
timerText.Text = count
task.wait(1)
end
-- Make the bridge not walkable
bridge.Transparency = 0.8
bridge.CanCollide = false
timerText.Text = ""
timerActive = false
end
local function buttonPressed(partTouched)
local character = partTouched.Parent
local humanoid = character:FindFirstChildWhichIsA("Humanoid")
print("part touched")
if humanoid and timerActive == false then
print("starting timer")
startTimer()
end
end
button.Touched:Connect(buttonPressed)
```
## Summary
Loops can be combined with different means of interaction to create fun gameplay moments. In this tutorial, a timed bridge is created using a for loop that functions as a countdown. During the countdown, players are given a limited time to get across.

View file

@ -0,0 +1,186 @@
---
title: Glow lights with for loops
description: Create glowing lights in Roblox Studio using a for loop. This practical example teaches computer science with Roblox.
next: /tutorials/fundamentals/coding-4/creating-a-timed-bridge
prev: /tutorials/fundamentals/coding-4/intro-to-for-loops
---
To practice for loops, you'll create a lamp that gradually glows brighter and then dims over time. This script can then be applied to any other lights in a project, whether it's a street light or glowing crystal.
<video controls src="../../../assets/education/coding-4/glowing-light-finished.mp4" width="100%"></video>
## Set up the part and script
The lamp will be a part with an attached light and script.
1. To make it easier to see the light, change the 3D world to **night time**. In the **Explorer** ⟩ **Lighting**, change **ClockTime** to `0`.
<img src="../../../assets/education/coding-4/glowing-lights-setClockTime.png" alt = "image" />
2. Create a new part or model named Lamp.
<img src="../../../assets/education/coding-4/glowing-lights-lightPart.jpg" width="75%" />
3. Select Lamp, and add a **light**, such as a PointLight or SpotLight. You'll work with the brightness property of the light to create a glowing lamp.
<img src="../../../assets/education/coding-4/florLoop_lightAdded.png" width="50%" />
4. In Lamp, add a new script named GlowScript. In that script, create variables to store the lamp part and the point light.
```lua
local lightPart = script.Parent
local light = lightPart.SpotLight
```
<Alert severity="warning">
The specific path to the light and part might differ based on the model you're using. Be sure to double check in the Explorer.
</Alert>
5. Next, create a variable to hold how much the light's brightness will change each time the loop runs. Then, add another variable for how many seconds the loops will wait before running again.
```lua
-- How much the light's brightness will change each time
local brightnessChange = 1
-- How often in seconds the light will change brightness
local timeChange = 1
```
## Make the lamp glow
The lamp will use two **for loops**, one that counts up to make the lamp brighter, and one that counts down to dim it. Each for loop will have a control variable called currentBrightness. That way, as the for loop's control variable goes up and down, so will the brightness of the light.
### First loop (light increase)
Remember, a for loop starts with keyword `for` followed by a control variable. This script will set the brightness value of the light to value in the control variable.
1. Code the for loop using the following values. Remember to separate the control variable and end values with a comma.
- **Control variable**: `currentBrightness`
- **Start value**: 0
- **End value**: 5
- **Increment Value**: `brightnessChange`
```lua
local timeChange = 1
for currentBrightness = 0, 5, brightnessChange do
end
```
2. In scope of the for loop, set the brightness property of the light to the value in the control variable by typing `light.Brightness = currentBrightness`. Now, when the loop runs, the light will become brighter.
```lua
for currentBrightness = 0, 5, brightnessChange do
light.Brightness = currentBrightness
end
```
3. So the change doesn't happen all at once, add a wait function using the value in `timeChange`.
```lua
for currentBrightness = 0, 5, brightnessChange do
light.Brightness = currentBrightness
task.wait(timeChange)
end
```
4. Run the experience to see the light increase in brightness each second.
<video controls src="../../../assets/education/coding-4/glowing-light-increase.mp4" width="100%"></video>
<Alert severity="info">
Depending on the lighting in your project, you make need to adjust the brightness variables, or the environment's lighting.
</Alert>
If you can't see the brightness change over time in the first loop:
- Make sure that `light.Brightness = currentBrightness` is between the do and end of your for loop.
- Check that `timeChange` is at least 1 or higher. Smaller numbers will make the brightness change faster, but be harder to see over time.
- Make sure that the first line of your for loop has two total commas separating the control variable, end value, and increment value.
### Second loop (light decrease)
To dim the light, use a second for loop. The values of this loop will be reversed so the light starts bright and each second, gets dimmer.
1. Code a second for loop that decreases the brightness over time. The solution is in the code box below. Use the following values:
- **Control Variable** - `currentBrightness` set to 5, the end of the last loop.
- **End** - 0, turning off the light.
- **Increment** - subtract `brightnessChange`.
```lua
-- Second loop dims lamp
for currentBrightness = 5, 0, -brightnessChange do
light.Brightness = currentBrightness
task.wait(timeChange)
end
```
2. Run your experience; you should see the light brighten and then dim.
<video controls src="../../../assets/education/coding-4/glowing-light-singleLoop.mp4" width="100%"></video>
### Make the light repeat
Right now, the light only turns on and off once. To make the lamp continuously glow on and off, the for loops will be placed inside a repeating while loop.
1. Under the for loops, create a new while loop.
```lua
while true do
end
```
2. Place both for loops inside a while loop. Indent the for loops to make them easier to tell apart from the while loop.
```lua
while true do
for currentBrightness = 0, 5, brightnessChange do
light.Brightness = currentBrightness
task.wait(timeChange)
end
for currentBrightness = 5, 0, -brightnessChange do
light.Brightness = currentBrightness
task.wait(timeChange)
end
end
```
3. Run the experience to see the light turn bright and dim continuously.
<video controls src="../../../assets/education/coding-4/glowing-light-finished.mp4" width="100%"></video>
## Finished light script
A finished version of the script can be referenced below.
```lua
-- Stores the light attached to this lamp
lightPart = script.Parent
light = lightPart.SpotLight
-- How much the light's brightness will change each time
local brightnessChange = 1
-- How often in seconds the light will change brightness
local timeChange = 0.2
while true do
for count = 0, 5, brightnessChange do
light.Brightness = count
task.wait(timeChange)
end
-- Second loop to turn off light
for count = 5, 0, -brightnessChange do
light.Brightness = count
task.wait(timeChange)
end
end
```
## Summary
To create complex effects in a project, scripts can use multiple loops, and even combinations of different types of loops. To code a glowing light, two loops are nested within a while loop. As coders add in more loops, be sure to check indentation so code can be easy to read.

View file

@ -0,0 +1,145 @@
---
title: Intro to for loops
description: Use for loops to repeat code in this lesson for Luau. This lesson explains how for loops work and includes practice scripts.
next: /tutorials/fundamentals/coding-4/glow-lights-with-for-loops
prev: /tutorials/fundamentals/coding-4/repeat-code-with-while-loops
---
There are different ways to make code run over and over. If you want the code to only run a certain amount of times, use a **for loop**. This article will cover the logic behind for loops and demonstrate some practical examples, such as coding a countdown.
## How for loops work
For loops use three values to control how many times they run: a **control** variable, an **end** value, and an **increment** value. Starting from the value of the control variable, the for loops will either count up or down each time it runs code inside the loop until it passes the end value. Positive increment values count up, and negative increment values count down.
<img src="../../../assets/education/coding-4/forLoop_annotatedExample.png" width="50%" />
<Alert severity="info">
Different computer languages might use other terminology with for loops. For instance, in C# or JavaScript, the end value might be called the condition.
</Alert>
## Steps in a for loop
To understand for loops, it helps to see a flow chart diagram showing the logic of how they progress.
First, the for loop compares the control variable with the end value.
<img src="../../../assets/education/coding-4/forLoopDiagram_generic1.png" width="75%" />
After running the code, the increment value is added to the control variable. The loop then checks the control variable and starts over.
<img src="../../../assets/education/coding-4/forLoopDiagram_generic2.png" width="75%" />
Once the control variable passes the end value, the loop will stop. For example, if a loop has an end value of 10, once the control variable has passed 10, the for loop will stop.
<img src="../../../assets/education/coding-4/forLoopDiagram_generic3.png" width="75%" />
## Code a countdown
To see how a for loop works, use these steps to code a for loop that starts at 10 and counts down to 0, one number at a time. Every time the loop runs, it'll print the current value inside the control variable.
1. In **ServerScriptService**, create a new script named PracticeLoop. In the script, start by typing the keyword `for`.
```lua
for
```
2. Create a **control variable** named `count` and set a starting value of 10.
```lua
for count = 10
```
3. Set the **end value** to 0, by typing `, 0`. Make sure to include a comma to separate the values.
```lua
for count = 10, 0
```
4. Create an **increment value** of -1 by typing `, -1`. After the loop has finished its action, it'll add the increment value to the control variable, count. Because the increment is negative, it'll be subtracted when added to the control variable.
```lua
for count = 10, 0, -1
```
<Alert severity="info">
A for loop doesn't explicitly need an increment. Without one, the loop will, by default, add 1 after each loop.
`for count = 10, 0`
</Alert>
5. To finish the for loop, type do and press <kbd>Enter</kbd> to add `end`. Any code typed between `do` and `end` will run each time the loop repeats.
```lua
for count = 10, 0, -1 do
end
```
6. Inside the loop, create a countdown by printing the value of the control variable, `count`, and then delay the script with a wait function.
```lua
for count = 10, 0, -1 do
-- Prints the current number the for loop is on
print(count)
-- Wait 1 second
task.wait(1)
end
```
7. Run the project and watch the Output window to see the for loop.
Notice that the loop will print out the current value of count each time it goes through an **iteration**. An iteration is the complete process of checking the control value, running code, and updating the increment value. Because the control variable starts at 0 and has to go pass 10, the loop will go through 11 iterations before stopping.
### Troubleshooting tips
At this point, if the loop doesn't work as intended, try one of the following below.
- Check that you have **two commas** separating the numbers in your for loop. Having extra or missing commas will make the loop not start.
- If the for loop prints all at once, make sure that there is a wait function that uses at least 1 second.
## Different for loop examples
Changing the three values of a for loop will change how the loop functions. Below are different examples of for loops with different start, end, and increment values. Try putting them into scripts and see what happens.
### Count up by one
```lua
for count = 0, 5, 1 do
print(count)
task.wait(1)
end
```
### Count up in even numbers
```lua
for count = 0, 10, 2 do
print(count)
task.wait(1)
end
```
### If for loops don't run at all
If the control variable starts out **beyond** the end value, like in the example below, the for loop won't run at all.
```lua
for count = 10, 0, 1 do
print(count)
task.wait(1)
end
```
In this case, the for loop is counting up and checking if count is greater than 0. When the for loop does it's first check, it sees that 10 is greater than 0, and so it'll stop the loop without printing anything.
## Summary
A for loop is a common type of loop that's used when a set of instructions should repeat a specific amount of times. To create a for loop, use three variables with the syntax below:
```lua
for count = 0, 10, 1 do
print(count)
end
```
In the example above, the loop will start at 0. For each loop, it will print the count variable, add 1 to count, and finally finish looping when count is equal to 10.

View file

@ -0,0 +1,66 @@
---
title: Loops
description: Learn how to use loops like while and for loops in this tutorial series for Roblox Studio. Great for beginners learning Luau or computer science.
next: /tutorials/fundamentals/coding-4/repeat-code-with-while-loops
prev: /tutorials/fundamentals/coding-3/give-points
---
### Series description
In computer science, loops are a common feature in many scripts, often used to repeat sets of code. This series will cover two of the most common loops: for and while loops.
### Objectives and prerequisites
<table>
<tbody>
<tr>
<td width="20%"><b>Learning objectives</b></td>
<td>
Understand situations where loops are useful as opposed to alternative forms of writing a script.
Be able to write out for and while loops, while identifying the syntax for both.
</td>
</tr>
<tr>
<td><b>Prerequisites</b></td>
<td>
Have a general understanding of variables in Luau.
</td>
</tr>
</tbody>
</table>
### Series Contents
<table>
<thead>
<tr>
<th>Article</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>[Repeat code with while Loops](./repeat-code-with-while-loops.md)</td>
<td>Learn how to repeat code to create a color changing part.</td>
</tr>
<tr>
<td>[Intro to for loops](./intro-to-for-loops.md)</td>
<td>Use a common loop that repeats instructions for a set amount of times.</td>
</tr>
<tr>
<td>[Loops practice: glowing lights with for loops](./glow-lights-with-for-loops.md)</td>
<td>Practice using for loops by making lights glow.</td>
</tr>
<tr>
<td>[Loops Practice: Creating a Timed Bridge](./create-a-timed-bridge.md)</td>
<td>A more advanced implementation of a for loop that makes a bridge disappear and reappear.</td>
</tr>
<tr>
<td>[Nesting loops](./nested-loops.md)</td>
<td>Add a loop within a loop for more complex behavior and code.</td>
</tr>
</tbody>
</table>

View file

@ -0,0 +1,362 @@
---
title: Nested loops
description: Learn how to use nested loops. This computer science lesson uses Luau to combine multiple nested for loops.
next: /tutorials/fundamentals/coding-5/landing
prev: /tutorials/fundamentals/coding-4/create-a-timed-bridge
---
Nesting loops allows you to repeat tasks in batches. For example, baking three batches of six cupcakes, or assigning weapons to players on two teams.
## How nested loops run
When loops are nested, scripts go line by line until it reaches the next loop. The inner loop will run until it's condition is met before returning to the outer loop.
### Nested loop logic
The following diagram shows the steps a loop takes.
<table>
<tbody>
<tr>
<td>
<ul>
<li>Outer loop: code runs line-by-line until it reaches the inner loop.</li>
<li>Outer loop: code runs line-by-line until it reaches the inner loop.</li>
<li>Outer loop: code runs line-by-line until it reaches the inner loop.</li>
</ul>
</td>
<td>
<img src="../../../assets/education/coding-4/NestedLoopsDiagram300x500.png" width="100%" />
</td>
</tr>
</tbody>
</table>
### Nested loop example
Nested loops can seem somewhat abstract, so a visual example can help. For this exercise, copy and paste a sample script and run it in Studio. This script will create towers of parts. The outer loop will control how many parts to make, while the inner loop will create the actual batch.
1. Create a new script in **ServerScriptService** named PartMaker. Copy the code below.
```lua
local numberOfBatches = 7
local partsPerBatch = 5
local partsMade = 0
-- Makes a single cube
local function createPart()
local part = Instance.new("Part")
part.Size = Vector3.new(2, 2, 2)
part.CFrame = CFrame.new(20, 0, 20)
part.Color = currentColor
part.Parent = workspace
end
-- Outer loop
for partBatch = 1, numberOfBatches do
print("Top outer loop: part batch " .. partBatch)
currentColor = Color3.fromRGB(math.random(0, 255), math.random(0, 255), math.random(0, 255))
-- Inner loop
for partNumber = 1, partsPerBatch do
createPart()
print("Inner loop: part " .. partNumber)
partsMade += 1
task.wait(0.5)
end
print("Bottom outer loop: " .. partsMade .. " parts made so far.")
task.wait(2)
end
```
2. Watch as the script spawns a different batch of colored parts. After going through one batch, it'll pause for 2 seconds. The print statement in the outer loop will run only one time per completed inner loop.
## Nested for loop tower
Each loop has its own set of code, so can be responsible for different tasks. One thing nested loops can do is change the placement of where an object spawns to create a tower like the one in this video. There's three different loops, one each for controlling where along the width, length, and height of the tower the cube spawns.
<video controls src="../../../assets/education/coding-4/LoopingTower2_Compressed.mp4" width="100%"></video>
## Code a cube maker script
To practice nested loops, you'll make a script that creates a tower of cubes. For the cube tower script, first code a function that spawns a single cube. The tower will be built by repeatedly calling this function.
### Set up the script
For the cube tower script, first code a function that spawns a single cube. The tower will be built by repeatedly calling this function.
1. **Delete** the PartMaker script or disable it (in the script properties, check Disabled). If you don't, there will be two scripts making parts at the same time in the same place.
2. Create a new script named TowerBuilder. Add variables for tower size and cube size at the top.
```lua
local TOWER_SIZE = 4
local CUBE_SIZE = 2
```
<Alert severity="info">
Notice how the variables above are all capitalized. These are called **constants**, or variables that don't change. To set them apart from variables that will be changed within the script, type them using capitals and underscores.
</Alert>
3. Add a local function named `makeCube()` that creates a single square cube using `CUBE_SIZE`.
```lua
local TOWER_SIZE = 4
local CUBE_SIZE = 2
-- Creates individual cubes
local function makeCube()
local cube = Instance.new("Part")
cube.Size = Vector3.new(CUBE_SIZE, CUBE_SIZE, CUBE_SIZE)
end
```
4. Set the cube's color to a variable which will be updated in the nested loops.
```lua
local function makeCube()
local cube = Instance.new("Part")
cube.Size = Vector3.new(CUBE_SIZE, CUBE_SIZE, CUBE_SIZE)
cube.Color = currentColor
end
```
5. Lastly, **parent** the new cube to the workspace so it appears.
```lua
local function makeCube()
local cube = Instance.new("Part")
cube.Size = Vector3.new(CUBE_SIZE, CUBE_SIZE, CUBE_SIZE)
cube.Color = currentColor
cube.Parent = workspace
end
```
<Alert severity="info">
In Roblox code, once an object is created by script, it's recommended to parent it at the end. It's faster to make changes to an instance before there is a physical object in the 3D world.
</Alert>
### Spawn in different directions
To create a tower, spawn cubes at specific points by setting the X, Y, Z properties of each new cube. X and Z are side to side. Y is up and down.
1. In `makeCube()`, add parameters for `spawnX`, `spawnY`, and `spawnZ`. These numbers will set each new cube's spawn location.
```lua
-- Creates individual cubes
local function makeCube(spawnX, spawnY, spawnZ)
local cube = Instance.new("Part")
cube.Size = Vector3.new(CUBE_SIZE, CUBE_SIZE, CUBE_SIZE)
cube.Color = currentColor
cube.Parent = workspace
end
```
2. Inside the function, set the cube's CFrame property to a new CFrame using the `spawnX`, `spawnY`, `spawnZ` parameters.
```lua
local function makeCube(spawnX, spawnY, spawnZ)
local cube = Instance.new("Part")
cube.Size = Vector3.new(CUBE_SIZE, CUBE_SIZE, CUBE_SIZE)
cube.Color = currentColor
cube.CFrame = CFrame.new(spawnX, spawnY, spawnZ)
cube.Parent = workspace
end
```
<Alert severity="info">
In Roblox, CFrame is a data type used to store 3D position and orientation. It's used to place objects in a world.
</Alert>
### Spawn with nested loops
The script will have three loops total, one each for the length, width, and height of the tower. To complete an entire floor before moving upwards, start with setting the Y coordinate in the first, outermost loop.
1. Under the `makeCube()` function, Create a for loop to set how **high** each cube spawns.
- **Control variable**: `heightIndex = 1`
- **End point**: `TOWER_SIZE`
- Inside the loop, add: local spawnY = (heightIndex - 1) \* CUBE_SIZE
```lua
-- Builds tower
for heightIndex = 1, TOWER_SIZE do
local spawnY = (heightIndex - 1) * CUBE_SIZE
end
```
<Alert severity="info">
The calculation for `spawnY` makes sure the first cube spawns at ground height and then moves over the space of a single cube every time. Ground level is at 0, which is why 1 needs to be subtracted from the `heightIndex`.
</Alert>
2. With the first loop for height finished, start on the second. Inside the first for loop, add a new for loop for where to place the cube along the length of the tower.
- **Control variable**: lengthIndex = 1
- **End point**: `TOWER_SIZE`
- Inside that loop add: local spawnX = lengthIndex \* CUBE_SIZE
```lua
for heightIndex = 1, TOWER_SIZE do
local spawnY = (heightIndex - 1) * CUBE_SIZE
for lengthIndex = 1, TOWER_SIZE do
local spawnX = lengthIndex * CUBE_SIZE
end
end
```
<Alert severity="warning">
When working with nested loops, it's important to make sure code is well indented. This helps make your code readable and organized.
</Alert>
3. Inside the **second** loop, add a **third** for loop for the tower **width**. In this final loop, call `makeCube()` and pass in the X,Y, Z parameters.
- **Control variable**: `widthIndex = 1`
- **End point**: `TOWER_SIZE`
- Inside the loop add:
- `local spawnZ = widthIndex * CUBE_SIZE`
- `makeCube(spawnX, spawnY, spawnZ)`
- A wait time of 0.25 so you can watch the tower be built.
```lua
-- Builds tower
for heightIndex = 1, TOWER_SIZE do
local spawnY = (heightIndex - 1) * CUBE_SIZE
for lengthIndex = 1, TOWER_SIZE do
local spawnX = lengthIndex * CUBE_SIZE
for widthIndex = 1, TOWER_SIZE do
local spawnZ = widthIndex * CUBE_SIZE
makeCube(spawnX, spawnY, spawnZ)
task.wait(0.25)
end
end
end
```
4. To have each floor be a random color, change `currentColor` to random `RGB` numbers in the same loop in which you create a new floor.
```lua
for heightIndex = 1, TOWER_SIZE do
local spawnY = (heightIndex - 1) * CUBE_SIZE
currentColor = Color3.fromRGB(math.random(0, 255), math.random(0, 255), math.random(0, 255))
for lengthIndex = 1, TOWER_SIZE do
local spawnX = lengthIndex * CUBE_SIZE
for widthIndex = 1, TOWER_SIZE do
local spawnZ = widthIndex * CUBE_SIZE
makeCube(spawnX, spawnY, spawnZ)
task.wait(0.25)
end
end
end
```
5. Run the project and wait to see that a full tower has been created without any errors in the Output window.
<video controls src="../../../assets/education/coding-4/nestedLoop-finalExample.mp4" width="100%"></video>
## Optional challenges
Below are different self-directed challenges that use nested loops in different ways. Try and code on your own before looking at the solution.
### Fade away parts
As the tower is built, have the parts fade in transparency from left to right.
<img src="../../../assets/education/coding-4/Fade_480x320.png" width="60%" />
The code solution is below.
```lua
local TOWER_SIZE = 6
local CUBE_SIZE = 2
-- Creates individual cubes
local function makeCube(spawnX, spawnY, spawnZ)
local cube = Instance.new("Part")
cube.Size = Vector3.new(CUBE_SIZE, CUBE_SIZE, CUBE_SIZE)
cube.Color = currentColor
cube.Transparency = cubeTransparency -- Sets transparency
cube.CFrame = CFrame.new(spawnX, spawnY, spawnZ)
cube.Parent = workspace
end
-- Builds tower
for heightIndex = 1, TOWER_SIZE do
local spawnY = (heightIndex - 1) * CUBE_SIZE
currentColor = Color3.fromRGB(math.random(0, 255), math.random(0, 255), math.random(0, 255))
for lengthIndex = 1, TOWER_SIZE do
local spawnX = lengthIndex * CUBE_SIZE
cubeTransparency = (lengthIndex - 1) * 0.10 --Updates every loop starting at 0
for widthIndex = 1, TOWER_SIZE do
local spawnZ = widthIndex * CUBE_SIZE
makeCube(spawnX, spawnY, spawnZ)
task.wait(0.05)
end
end
end
```
### Rain down objects
Instead of parts, try spawning an actual object. The example here used cupcakes.
On your own, see if you can:
- Create an object from base parts. Make sure to weld all parts together so the object doesn't fall apart.
- Place the object in ServerStorage
- Modify the PartMaker found in the [Nested Loop Example](#nested-loop-example)to use your object instead of parts.
A sample is shown here.
<video controls src="../../../assets/education/coding-4/CupCakeBloopers_Compressed.mp4" width="100%"></video>
A code solution using cupcakes is included.
```lua
local numberOfBatches = 30
local cupcakesPerBatch = 6
local cupcakesBaked = 0
--Makes a single cupcake
local function makeCupcake()
local ServerStorage = game:GetService("ServerStorage")
local cupcake = ServerStorage.Cupcake:Clone()
local cup = cupcake.Cup
local frosting = cupcake.Frosting
cupcake:SetPrimaryPartCFrame(CFrame.new(0, 20, 0) * CFrame.Angles(0, 0, -90))
frosting.Color = frostingColor
cup.Color = cupColor
cupcake.Parent = workspace
end
-- Outer loop
for cupcakeBatch = 1, numberOfBatches do
print("Top outer loop: cupcake batch " .. cupcakeBatch)
frostingColor = Color3.fromRGB(math.random(0, 255), math.random(0, 255), math.random(0, 255))
cupColor = Color3.fromRGB(math.random(0, 255), math.random(0, 255), math.random(0, 255))
-- Inner loop
for cupcakeNumber = 1, cupcakesPerBatch do
makeCupcake()
print("Inner loop: cupcake " .. cupcakeNumber)
-- Track muffins baked
cupcakesBaked += 1
task.wait(0.5)
end
print("Bottom outer loop: " .. cupcakesBaked .. " cupcakes baked so far.")
end
```
## Summary
To accomplish more complex tasks, coders will find it helpful to combine multiple loops, and even different types of loops. All loops can be nested, meaning that one loop is inside another. Nested loops follow the same logic as any other loop. It starts in the first, outermost loop, runs tasks through inner loops, and then cycles back to the first loop if applicable.

View file

@ -0,0 +1,194 @@
---
title: Repeat code with while loops
description: Learn how to use while loops with Roblox's Luau language in this computer science lesson.
next: /tutorials/fundamentals/coding-4/intro-to-for-loops
prev: /tutorials/fundamentals/coding-4/landing
---
Many things in computer science or game development often repeat. For instance, an app might update content in a feed every few seconds, or a game might reward players a prize every day they're logged in. To accomplish this behavior, coders often use **loops**.
In computer science, a **loop** is a coding pattern that repeats a set of instructions, often until a specific condition is met. To practice this, you'll code a part that changes colors indefinitely. Later lessons will show how to stop the looping.
<video controls src="../../../assets/education/coding-4/loops-and-parts-finishedPart.mp4" width="100%"></video>
## Set up the part and script
Use any Roblox project for this exercise. When finished, this part can be used as a way of decorating an environment.
1. Create a new part with a descriptive name. This lesson uses **LoopingPart**.
2. In **ServerScriptService**, add a new script named LoopingScript.
3. In the script, delete `Hello World` and write a **comment** stating the purpose of this script.
```lua
-- Changes the color of LoopingPart every few seconds
```
## Use variables to store a part
Variables can also hold references to objects besides strings. For example, when a script knows the reference to a part, the script can change it.
Rather than typing `workspace.NameOfYourPart` over and over, that entire line can be stored inside a local variable. Local variables are created by typing `local` and then the name of the variable.
For example: `local nameOfVariable`.
<Alert severity="info">
A local variable only works in the script where it was created. If a local variable named `part1` is created in Script1, it cannot be used in Script2. Most variables you use will be local variables.
</Alert>
1. Under the comment, create a local variable by typing `local loopingPart`.
```lua
-- Changes the color of LoopingPart every few seconds
local loopingPart
```
2. Set the variable to the looping part by typing `= workspace.LoopingPart` on the same line. Remember that the `=` operator sets the value of a variable to whatever is on the right of it.
```lua
-- Changes the color of LoopingPart every few seconds
local loopingPart = workspace.LoopingPart
```
<Alert severity="info">
Remember that the `=` operator sets the value of a variable to whatever is on the right of it.
</Alert>
## While loops
Before creating the while loop for the color changing part, it's worthwhile to explain its syntax. A while loop has three components:
- The `while` keyword.
- A condition, always after the keyword.
- Instructions, between the `do` and `end` keywords.
In loops, conditions can be a variety of logical statements. Some examples might be if two numbers are the same. A loop will run if its condition is true.
Notice in the sample below, the condition is true, meaning this loop will run forever. In later lessons, you'll code specific conditions that stop.
```lua
while true do
print("This loop is running")
end
```
## Code a while loop
Next, you'll set up the while loop for the color changing part.
1. On the next line type `while true do`. Then, press <kbd>Enter</kbd> to autocomplete and add the word `end`.
```lua
-- Changes the color of loopingPart every few seconds
local loopingPart = workspace.LoopingPart
-- Looping Code
while true do
end
```
<Alert severity="info">
You might have noticed the editor automatically added `end` to the script and indented the next line of code. Indenting makes code easier to read. Instructions in a loop should **always** be indented.
</Alert>
### Add code in the loop
With the while loop created, instructions can be added to change the part's color over time. Inside the loop, add a line of code for each color. Each color will use RGB values, a way of storing colors as numbers in computer science.
1. Between `while true do` and `end`, set the Color property of the part to `Datatype.Color3.fromRGB()`.
```lua
local loopingPart = workspace.LoopingPart
while true do
loopingPart.Color = Color3.fromRGB()
end
```
2. Setting the color can be done using a color picker in Studio. To do so, left click inside the `()` next to `fromRGB`. Then, click on the color wheel icon. Once you have a desired color, press OK to automatically add the color value in the code.
```lua
local loopingPart = workspace.LoopingPart
while true do
loopingPart.Color = Color3.fromRGB(82, 227, 255)
end
```
<Alert severity="info">
If desired, a color can be created manually by assigning a value in each number from 0 to 255.
</Alert>
### Make the script wait
If you add a second line of color changing code right now, it would change the brick's color so fast you might not even see the first color go by. To make the script wait before running the next line of code, use a `Library.task.wait()` function.
1. On the line after changing the brick color, type `task.wait(3)`. Whatever number placed inside the `()` is how many seconds the script will wait.
```lua
local loopingPart = workspace.LoopingPart
while true do
loopingPart.Color = Color3.fromRGB(82, 227, 255)
task.wait(3)
end
```
2. Under the wait function, repeat the same process of adding a new color. Finish it with an additional wait function.
```lua
while true do
loopingPart.Color = Color3.fromRGB(82, 227, 255)
task.wait(3)
loopingPart.Color = Color3.fromRGB(177, 52, 255)
task.wait(3)
end
```
<Alert severity="warning">
As you add more code in the loop, make sure it's all in **scope**, meaning code is in the right place. In order for code to run in the loop, it has to be between the `while true do` and before `end`.
</Alert>
3. Test the code and see if the colors change.
<video controls src="../../../assets/education/coding-4/loops-and-parts-finishedPart.mp4" width="100%"></video>
**Troubleshooting Notes**
At this point, if the color changing part doesn't work as intended, try one of the following below.
**Issue**: Colors are skipped
- Make sure you have a wait function between each color change, especially at the last line.
- Check that all the color change and wait code is between the `while true do` and `end` sections.
**Issue**: Part is still gray or doesn't change color as intended
- Make sure all RGB values have numbers from 0 to 255, are whole or decimals, and are separated by commas.
- The numbers inside the `()` of a wait function should be greater than 1. It's possible that if a wait is too short, you may not see that color.
## Complete color looping part script
```lua
-- Create a variable to store the part
local loopingPart = workspace.LoopingPart
-- Looping Code
while true do
-- Changes loopingPart's color
loopingPart.Color = Color3.fromRGB(82, 227, 255)
-- Wait 3 seconds before next instruction
task.wait(3)
loopingPart.Color = Color3.fromRGB(177, 52, 255)
task.wait(3)
end
```
## Summary
Loops are a common element in most computer languages. They are used to repeat instructions, sometimes until specific conditions are met. In this article, the while loop is used to repeat instructions forever. To create a while loop that repeats forever, use the syntax below, being sure to include instructions between the `do` and `end` keywords.
```lua
while true do
-- Instructions
end
```