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
EasyThe 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():
keysholds the four digit buttons in order:keys[0]types 1,keys[1]types 2,keys[2]types 3 andkeys[3]types 4. Hook them in aforloop, each with a lambda that callsPress.clearButton, with one lambda, empties the code typed so far (entered) and shows it withShowCode().
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;
}
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Building Real Games
2Buttons and Screens
Buttons and onClickLambdasWiring in the InspectorPanels On and OffHealth BarsRecap: Upgrade Shop5Saving with PlayerPrefs
Save a NumberLoad with a DefaultHigh ScoreSave SettingsRecap: Coins in the Bank3The Game Manager
One Script Runs the GameThe SingletonGame StatesSwitching on the StateRecap: Round Manager6Project: Endless Runner
Three LanesObstacles Ahead9The New Input System
Two Input SystemsKeyboard and MousePressed This FrameInput ActionsRecap: Input Swap