Summary
Control flow determines which code runs and how many times it runs. In C#, if/else statements branch on conditions, for loops repeat a known number of times, and while loops repeat until a condition changes. Almost every game system, including collecting pickups, tracking health and processing waves of enemies, is built from these three constructs working together.
Key ideas
Comparison operators:
| Operator | Meaning |
|---|---|
| == | Equal to |
!= | Not equal to |
< | Less than |
<= | Less than or equal to |
> | Greater than |
>= | Greater than or equal to |
Logical operators:
| Operator | Meaning |
|---|---|
&& | AND: both conditions must be true |
|| | OR: at least one condition must be true |
! | NOT: inverts a boolean value |
for loop: Use when the number of iterations is known in advance. This usually means iterating over an array or repeating a fixed number of times. The loop variable i is conventional but not required.
while loop: Use when the number of iterations is not known in advance. This means looping until a condition becomes false, such as health reaching zero or a target score being reached.
foreach loop: Use when you want to visit every item in a collection and you do not need the index. It is often the clearest way to loop through a List<T> or array.
Ternary operator: A compact inline conditional that evaluates to one of two values. Useful for short label or flag assignments.
In practice
if / else if / else:
int health = 20;
int score = 150;
if (health <= 0)
{
Debug.Log("Game over!");
}
else if (health < 25)
{
Debug.Log("Low health warning!");
}
else
{
Debug.Log("Health: " + health);
}
// Logical operators
if (health <= 0 && lives == 0)
{
Debug.Log("No lives remaining.");
}for loop, iterating over an array:
int[] coinValues = { 10, 25, 10, 50, 15 };
int total = 0;
for (int i = 0; i < coinValues.Length; i++)
{
total += coinValues[i];
}
Debug.Log("Total coins: " + total);foreach loop, iterating without an index:
string[] collectedItems = { "Key", "Potion", "Map" };
foreach (string item in collectedItems)
{
Debug.Log("Collected: " + item);
}Use foreach when you just want each item. Use for when you need i for the position, want to skip around by index, or need to replace elements in place.
while loop, condition-based repetition:
int health = 100;
int damagePerTurn = 15;
int turn = 0;
while (health > 0)
{
health -= damagePerTurn;
if (health < 0) health = 0; // clamp
turn++;
Debug.Log("Turn " + turn + ": health " + health);
}
Debug.Log("Defeated after " + turn + " turns.");Should I use if or while to check if a player is alive?
Use if for a normal gameplay check:
if (playerHealth > 0)
{
Debug.Log("Player is alive.");
}That asks one question once, at this point in the code.
Use while only if you genuinely want to keep looping until the condition changes:
while (playerHealth > 0)
{
playerHealth -= poisonDamagePerTick;
}That is much rarer in everyday Unity gameplay code. Most of the time, checking whether a player is alive is an if, not a while.
Ternary operator:
// condition ? value-if-true : value-if-false
string status = (health <= 20) ? " [LOW HEALTH]" : "";
Debug.Log("Enemy HP: " + health + status);Loops and conditions combined, the core game logic pattern:
int[] enemyHealth = { 0, 45, 0, 80, 12 };
int aliveCount = 0;
for (int i = 0; i < enemyHealth.Length; i++)
{
if (enemyHealth[i] > 0)
{
aliveCount++;
if (enemyHealth[i] <= 20)
Debug.Log("Enemy " + i + " critically low: " + enemyHealth[i] + " HP");
}
}
Debug.Log(aliveCount + " enemies remaining.");Variables declared inside a loop body:
for (int i = 0; i < enemyHealth.Length; i++)
{
int currentHealth = enemyHealth[i];
Debug.Log(currentHealth);
}currentHealth is created fresh each iteration because it is declared inside the loop body. You can think of it as a temporary variable that only exists for that single pass through the loop.
By contrast, the loop counter i keeps changing value across iterations because it is declared in the for (...) header and then updated by the loop itself.
Gotchas
- A
whileloop with a condition that never becomes false will freeze Unity. Always ensure something inside the loop modifies the condition variable. - Clamping after arithmetic (
if (health < 0) health = 0;) is a recurring pattern. Forgetting it allows values to go negative, which can cause unexpected behaviour in UI and game logic. - The
forloop counter variableiis zero-based. When printing “Enemy 1, Enemy 2…” for human display, printi + 1rather thani. - A
foreachloop gives you each item in turn, but not the index. If you need both the item and its position, use aforloop instead.
Practice
Trace this code by hand before running it:
int[] enemyHealth = { 0, 10, 35, 5 };
int alive = 0;
int weak = 0;
for (int i = 0; i < enemyHealth.Length; i++)
{
if (enemyHealth[i] > 0)
{
alive++;
if (enemyHealth[i] <= 10)
{
weak++;
Debug.Log("Weak enemy at index " + i);
}
}
}
Debug.Log("Alive: " + alive);
Debug.Log("Weak: " + weak);Then change the rule so that enemies with exactly 0 health print "Defeated enemy at index X". Keep the alive and weak counts correct.
Self-test
- When should you use
ifinstead ofwhile? - When should you use
forinstead offoreach? - What is the final value of
alivein the practice code? - What is the final value of
weakin the practice code? - Why is
currentHealthdeclared inside the loop body in the earlier example?
Answers
- Use
ifwhen you need to make one decision at the current point in the code. Usewhileonly when the code must repeat until a condition changes. - Use
forwhen you need the index, need to replace items by position, or need more control over the loop. Useforeachwhen you only need each item. alivebecomes3because three enemies have health greater than0.weakbecomes2because the enemies at index1and index3have health greater than0and less than or equal to10.currentHealthis declared inside the loop body because it is temporary. A fresh value is read for each pass through the loop.
Related
- csharp-variables-and-types: the variables used in conditions and loops
- csharp-methods: enclosing loop and condition logic in named methods
- csharp-collections: looping through
List<T>and other collections - monobehaviour-lifecycle: where game loops run in Unity (
Update,Start)