Basic Unity Course: Loops – foreach

Hello! In this tutorial, we will take a closer look at one of the very important programming concepts in Unity: loops, particularly the foreach statement. Loops provide the ability to process tasks repeatedly, enhancing the utility of the code and allowing us to perform repetitive tasks efficiently. The foreach statement is very useful when dealing with iterable data, such as collections (arrays, lists, etc.).

1. Concept of Loops

A loop is a structure that repeatedly executes specific code while a specified condition is true. Common loops include for, while, and foreach. Among these, the foreach statement allows direct access to each element of a collection, which helps improve code readability and reduce errors.

2. Basic Structure of the foreach Statement

The foreach statement has the following basic structure.

foreach (dataType variableName in collection) {
        // Code to be executed repeatedly
    }

2.1 Example: Using Arrays

As a simple example, let’s use the foreach statement to output all elements from an array.

using UnityEngine;

public class ForEachExample : MonoBehaviour
{
    void Start()
    {
        int[] numbers = { 1, 2, 3, 4, 5 };

        foreach (int number in numbers)
        {
            Debug.Log(number);
        }
    }
}

In the code above, each element of the numbers array is assigned to a variable called number one by one, and its value is output to the console.

3. foreach Statement and Collections

The foreach statement can be used not only with arrays but also with various collections like lists, hash sets, and dictionaries. Let’s look at examples for each type of collection.

3.1 Using Lists

A list is a dynamic array structure that allows elements to be added and removed. Here’s an example applying the foreach statement using a list.

using System.Collections.Generic;
using UnityEngine;

public class ForEachListExample : MonoBehaviour
{
    void Start()
    {
        List fruits = new List { "Apple", "Banana", "Cherry", "Durian" };

        foreach (string fruit in fruits)
        {
            Debug.Log(fruit);
        }
    }
}

In this example, each element of the fruits list is assigned to the variable fruit and then output to the console.

3.2 Using Hash Sets

A hash set is a structure that stores unique values and is mainly used to avoid duplicates. Here’s an example using a hash set.

using System.Collections.Generic;
using UnityEngine;

public class ForEachHashSetExample : MonoBehaviour
{
    void Start()
    {
        HashSet uniqueNumbers = new HashSet { 1, 2, 3, 4, 5, 1, 2 };

        foreach (int number in uniqueNumbers)
        {
            Debug.Log(number);
        }
    }
}

Here, even though the uniqueNumbers hash set contains duplicate numbers, the output values are unique.

3.3 Using Dictionaries

A dictionary is a collection of key-value pairs. Here’s an example using a dictionary.

using System.Collections.Generic;
using UnityEngine;

public class ForEachDictionaryExample : MonoBehaviour
{
    void Start()
    {
        Dictionary ageMap = new Dictionary
        {
            { "Hong Gil-dong", 25 },
            { "Kim Cheol-su", 30 },
            { "Lee Young-hee", 28 }
        };

        foreach (KeyValuePair entry in ageMap)
        {
            Debug.Log($"Name: {entry.Key}, Age: {entry.Value}");
        }
    }
}

Using the dictionary’s KeyValuePair, we can output each name and age.

4. Performance Considerations of the foreach Statement

The foreach statement is very useful, but there are sometimes performance considerations to keep in mind. Particularly when iterating through large collections, performance can become critical. Here are some performance-related considerations when using the foreach statement.

4.1 Memory Allocation

In some cases, the foreach statement may create a copy of the collection and allocate additional memory. This primarily occurs with collections that are not arrays. In performance-critical games, using a for statement with direct indexing may be faster.

4.2 Collection Type

The memory allocation issue varies depending on the type of collection being used. For example, List manages memory efficiently, while LinkedList may be relatively slower due to the connections between nodes.

5. Practical Example Using the foreach Statement

Now let’s look at a more practical example using the foreach statement.

5.1 Creating Enemy Characters

The following example creates enemy characters in an array and uses the foreach statement to output the status of each character.

using UnityEngine;

public class Enemy
{
    public string Name;
    public int Health;

    public Enemy(string name, int health)
    {
        Name = name;
        Health = health;
    }
}

public class EnemyManager : MonoBehaviour
{
    void Start()
    {
        Enemy[] enemies = {
            new Enemy("Slime", 100),
            new Enemy("Goblin", 150),
            new Enemy("Dragon", 300)
        };

        foreach (Enemy enemy in enemies)
        {
            Debug.Log($"{enemy.Name}'s Health: {enemy.Health}");
        }
    }
}

5.2 My Own Object Pooling Example

Object Pooling is a pattern used to efficiently manage game objects that are frequently created and destroyed. Here’s a simple class example for object pooling.

using System.Collections.Generic;
using UnityEngine;

public class Bullet
{
    public GameObject bulletObject;
}

public class ObjectPool : MonoBehaviour
{
    private List bulletPool;

    void Start()
    {
        bulletPool = new List();
        for (int i = 0; i < 10; i++)
        {
            Bullet bullet = new Bullet();
            bullet.bulletObject = CreateBullet();
            bulletPool.Add(bullet);
        }

        foreach (Bullet bullet in bulletPool)
        {
            Debug.Log("Bullet created: " + bullet.bulletObject.name);
        }
    }

    GameObject CreateBullet()
    {
        GameObject bullet = new GameObject("Bullet");
        // Bullet initialization code
        return bullet;
    }
}

6. Conclusion

In this tutorial, we explored loops in Unity, particularly the foreach statement. The foreach statement allows us to traverse various collection types, making the code more concise and readable. However, we should not forget about performance considerations and it’s important to use it appropriately alongside other loops. This will enable us to handle repetitive tasks efficiently during game development.

Use the various elements of Unity to create an amazing game! Thank you.