Menu
CoddyTech

Lambdas

Part of the Building Real Games section of Coddy's Unity journey. Lesson 7 of 56.

AddListener takes a method with no parameters. To make a click call Paint(Color.red), which takes a color, write the method on the spot: () => Paint(Color.red). That is a lambda, a method with no name. The () holds its parameters, none here, and after => comes its body: one statement, or a block in { } for several:

public Button redButton;
public Button blueButton;
public Button resetButton;
public Renderer lamp;
private int changes;

void Start()
{
    redButton.onClick.AddListener(() => Paint(Color.red));
    blueButton.onClick.AddListener(() => Paint(Color.blue));
    resetButton.onClick.AddListener(() =>
    {
        changes = 0;
        lamp.material.color = Color.white;
    });
}

void Paint(Color color)
{
    lamp.material.color = color;
    changes++;
}

One Paint method serves both color buttons, each lambda passing its own color. A lambda captures the variables it uses: it does not copy their values, it reads them when it runs. The reset lambda sets the field changes each time it is clicked, long after Start() has ended.

That catches you in a loop. With swatches[i].onClick.AddListener(() => Paint(colors[i])); every lambda captures the same i, and by the time anyone clicks, the loop has ended with i equal to colors.Length: every swatch throws IndexOutOfRangeException. A variable declared inside the loop is a new one each time round, so copy i into one and capture the copy:

for (int i = 0; i < swatches.Length; i++)
{
    int index = i;
    swatches[i].onClick.AddListener(() => Paint(colors[index]));
}
challenge icon

Challenge

Easy

The vault opens with a three-digit code. Keypad.cs already has Press(int digit), which adds a digit to the code on screen and, after three, opens the door or shows Wrong, and ShowCode(), which shows what is typed so far. Hook up the buttons in Start():

  • keys holds the four digit buttons in order: keys[0] types 1, keys[1] types 2, keys[2] types 3 and keys[3] types 4. Hook them in a for loop, each with a lambda that calls Press.
  • clearButton, with one lambda, empties the code typed so far (entered) and shows it with ShowCode().

The code is 312. Press Play, open the vault, then Check.

Try it yourself

using UnityEngine;
using UnityEngine.UI;
using TMPro;

public class Keypad : MonoBehaviour
{
    public Button[] keys;
    public Button clearButton;
    public TMP_Text codeText;
    public GameObject door;
    public string secret = "312";
    private string entered = "";

    void Start()
    {
        ShowCode();
        // Hook each key to Press with its digit, and clearButton to clearing the code
    }

    void Press(int digit)
    {
        entered += digit;
        ShowCode();
        if (entered.Length == 3)
        {
            if (entered == secret)
            {
                door.SetActive(false);
                codeText.text = "Open";
            }
            else
            {
                codeText.text = "Wrong";
            }
            entered = "";
        }
    }

    void ShowCode()
    {
        codeText.text = "Code: " + entered;
    }
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Building Real Games