Menu
CoddyTech

Lambdas

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

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

Hook up the vault's keypad in Start().

  1. Loop over keys with for. In the loop, declare int digit = i + 1; and hook keys[i] to () => Press(digit).
  2. Hook clearButton to one lambda that sets entered = "" and calls ShowCode().

Press Play and type 3, 1, 2: the screen reads Open. 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;
    }
}

All lessons in Building Real Games

Practice on your own: Unity playground