Control Flow

What is Control Flow?


Control flow is how your code decides what to do, when to do it, and how many times to do it. It’s the logic engine of your game–controlling gameplay decisions, movement, AI behavior, win/loss conditions and more.

Why It Matters in Unity

In a game:

  • Should the door open?
  • Should the enemy chase you?
  • Should a player respawn or die?
  • Should coins be added or ignored?

All of these are controlled using control flow statements.

Types of Control Flow Statements

if / else if / else


These run code only if a condition is true.

C#
if (health <= 0)
{
    Debug.Log("You died.");
}
else if (health < 50)
{
    Debug.Log("Low health!");
}
else
{
    Debug.Log("You’re healthy!");
}


Example in Unity:

C#
if (Input.GetKeyDown(KeyCode.Space))
{
    Jump();
}


Switch Statement

An alternative to long chains of if/else. Great for handling multiple fixed cases.

C#
string state = "Walking";

switch (state)
{
    case "Idle":
        PlayIdle();
        break;

    case "Walking":
        PlayWalk();
        break;

    case "Running":
        PlayRun();
        break;

    default:
        Debug.Log("Unknown state");
        break;
}


When to use it:

  • Player modes
  • Item types
  • Menu selections


for Loops

Runs a block of code a set number of times

C#
for (int i = 0; i < 3; i++)
{
    Debug.Log("Loop count: " + i);
}


Examples in Unity

C#
for (int i = 0; i < enemies.Count; i++)
{
  enemies[i].TakeDamage(10);
}

Loop through all enemies and apply 10 damage to each.

foreach Loops

Used to go through every item in a collection.

C#
foreach (string name in playerNames)
{
    Debug.Log("Player: " + name);
}


Examples in Unity:

C#
foreach (GameObject enemy in GameObject.FindGameObjectsWithTag("Enemy"))
{
    enemy.SetActive(false);
}

Finds every gameObject in scene with tag “Enemy” and deactivates them.

while Loops

Repeats code as long as a condition is true.

C#
int i = 0;
while (i < 5)
{
    Debug.Log(i);
    i++;
}


Example in Unity

C#
while (playerInZone)
{
    HealPlayer();
    yield return new WaitForSeconds(1f);
}

Tip: Use while inside Coroutines to avoid freezing the game.

do while Loops

Like while loops but runs at least once before checking the condition. Perfect when you want “at least one guaranteed action”, even if the condition might not be true later. In a normal while, it might skip entirely if the condition is false right away.

C#
int coins = 0;
do
{
  Debug.Log("Still broke. . .");
  coins++;
}
while (coins < 1);


Examples in Unity

Loot Chest with guaranteed Rare Item

C#
  private string[] items = {"Common Sword", 
"Common Shield", "Rare Gem", "Common Potion" };

  private string selectedItem;

  void Start()
  {
    OpenChest();
  }
  
  void OpenChest()
  {
    do
    {
      int randomIndex = Random.Range(0, items.Length);
      selectedItem = items[randomInex];
      
      Debug.Log("Rolled: " + selectedItem);
    }
    while (!selectedItem.StartsWith("Rare"));
    
    Debug.Log("You obtained a rare item: " +
    selectedItem + "!");
  }

the do-while loop rolls an item from the chest. It keeps rolling until it gets an item that starts with “Rare”. It logs each roll so you can see how many tries it took.

do means run this code once no matter what.
while (condition) checks if it should repeat.

Gun Reloading Example
The player reloads bullets one at a time until the clip is full (would be great for revolvers and pump-action shotguns.

C#
public int roundsInCylinder = 3;
public int cylinderSize = 6;

void Start()
{
  Reload();
}

void Reload()
{
  do
  {
    roundsInCylinder++
    Debug.Log("Reloading... Current ammo: " + roundsInCylinder);
  }
  while (roundsInCylinder < cylinderSize);
  
  Debug.Log("Reload Complete!");
}

Starts with 3 rounds.
Reloads one round at a time.
Stops once rounds = cylinder size (6).
Guaranteed at least one reload action even if cylinder is already almost full.

break and continue

break = exit the loop
continue = skip this loop iteration

C#
for (int i = 0; i < 10; i++)
{
    if (i == 3) continue; // Skip 3
    if (i == 7) break;    // Stop at 7
    Debug.Log(i);
}


Combining Control Flow

You can mix control flow for powerful logic
break and continue are huge for making loops more responsive and natural.

C#
foreach (Enemy enemy in enemies)
{
    if (enemy.health <= 0)
    {
        enemy.Die();
        continue;
    }

    if (playerInRange)
    {
        enemy.Chase(player);
    }
}


Spawning enemies with random boss chance
Uses: do-while, if, and break

C#
using UnityEngine;

public class EnemySpawner : MonoBehaviour
{
    public GameObject enemyPrefab;
    public GameObject bossPrefab;
    public int maxEnemies = 10;

    void Start()
    {
        int spawned = 0;
        
        do
        {
            // 10% chance to spawn a boss
            if (Random.value < 0.1f)
            {
                Instantiate(bossPrefab, RandomPosition(), Quaternion.identity);
                Debug.Log("Boss spawned!");
                break; // End the loop early after spawning boss
            }
            else
            {
                Instantiate(enemyPrefab, RandomPosition(), Quaternion.identity);
                Debug.Log("Enemy spawned: " + spawned);
            }

            spawned++;
        }
        while (spawned < maxEnemies);

        Debug.Log("Spawning complete!");
    }

    Vector3 RandomPosition()
    {
        return new Vector3(Random.Range(-10f, 10f), 0, Random.Range(-10f, 10f));
    }
}

do-while keeps spawning enemies
if creates a 10 percent chance to spawn a boss
break exits loop early if boss is spawned


Damage Player until health runs out

C#
using UnityEngine;

public class DamagePlayer : MonoBehaviour
{
    public int playerHealth = 100;

    void Start()
    {
        while (playerHealth > 0)
        {
            int damage = Random.Range(5, 20);

            if (damage < 10)
            {
                Debug.Log("Weak hit, ignoring...");
                continue; // Skip weak hits
            }

            playerHealth -= damage;
            Debug.Log("Player took " + damage + " damage! Health: " + playerHealth);

            if (playerHealth <= 0)
            {
                Debug.Log("Player defeated!");
                break;
            }
        }
    }
}

while loop runs while the player is alive
if filters weak hits (attacks that would deal less than 10 damage)
continue skips weak damage
break ends loop if player dies

Common Mistakes and Troubleshooting


Using = instead of ==

C#
if (health = 0) // WRONG: assigns 0 to health

fix:

C#
if (health == 0) // Correct: checks if health is 0


Forgetting Braces {}

C#
if (isDead)
    Debug.Log("Game Over");
    Restart();  // ALWAYS runs — not part of `if`

fix:

C#
if (isDead)
{
    Debug.Log("Game Over");
    Restart();
}


Infinite while loops in Update()

C#
// This will FREEZE the game!
while (true)
{
    Debug.Log("Looping forever...");
}

fix: Only use while inside coroutines with yield, or use if and timers in Update.

Incorrect Loop Conditions

C#
for (int i = 10; i < 5; i++)  // This never runs!

fix: Ensure your loop makes logical sense. This loop starts at 10 and runs only while i < 5, so it never starts.

Modifying Collections While Looping

C#
foreach (var enemy in enemies)
{
    enemies.Remove(enemy); // Error!
}

fix: Use a for loop backward or store items to remove:

C#
for (int i = enemies.Count - 1; i >= 0; i--)
{
    if (enemies[i].health <= 0)
        enemies.RemoveAt(i);
}


Not using break in switch

C#
switch (weapon)
{
    case "Pistol":
        EquipPistol();
    case "Shotgun":
        EquipShotgun();  // Runs this too!
}

fix: Always use break; to stop after the matching case:

C#
case "Pistol":
    EquipPistol();
    break;


Quick Reference

IF Statements

C#
if (condition)
{
    // do this
}
else if (anotherCondition)
{
    // do this instead
}
else
{
    // fallback
}

SWITCH

C#
switch (value)
{
    case 0: DoSomething(); break;
    case 1: DoAnotherThing(); break;
    default: HandleUnknown(); break;
}

FOR Loop

C#
for (int i = 0; i < 5; i++)
{
    Debug.Log(i);
}

FOREACH Loop

C#
foreach (var item in list)
{
    UseItem(item);
}

WHILE Loop

C#
while (condition)
{
    DoSomething();
}

DO…WHILE Loop

C#
do
{
    TrySomething();
}
while (!Success());

BREAK / CONTINUE

C#
for (int i = 0; i < 10; i++)
{
    if (i == 5) continue; // Skip 5
    if (i == 8) break;    // Exit loop
}

TERNARY (Short If/Else)

C#
string status = (health > 0) ? "Alive" : "Dead";