Lambda
Thuộc phần Xây dựng trò chơi thực tế trong hành trình Unity của Coddy. Bài học 7 trên 60.
AddListener nhận một phương thức không có tham số. Để thao tác nhấp gọi Paint(Color.red), vốn nhận một màu, hãy viết phương thức ngay tại chỗ: () => Paint(Color.red). Đó là một hàm lambda (lambda), một phương thức không có tên. () chứa các tham số của hàm, ở đây không có tham số nào, còn phần thân hàm nằm sau =>: một câu lệnh hoặc một khối lệnh trong { } nếu có nhiều câu lệnh:
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++;
}Một phương thức Paint dùng chung cho cả hai nút màu, mỗi hàm lambda truyền vào màu riêng của nó. Hàm lambda nắm bắt các biến mà nó sử dụng: hàm không sao chép giá trị của chúng mà đọc các giá trị đó khi chạy. Hàm lambda đặt lại trường changes mỗi lần được nhấp, rất lâu sau khi Start() kết thúc.
Điều này có thể khiến bạn gặp lỗi trong vòng lặp. Với swatches[i].onClick.AddListener(() => Paint(colors[i]));, mọi hàm lambda đều nắm bắt cùng một i, và đến khi có người nhấp, vòng lặp đã kết thúc với i bằng colors.Length: mọi ô màu đều gây ra lỗi IndexOutOfRangeException. Biến được khai báo bên trong vòng lặp là một biến mới ở mỗi lần lặp, vì vậy hãy sao chép i vào biến đó rồi nắm bắt bản sao:
for (int i = 0; i < swatches.Length; i++)
{
int index = i;
swatches[i].onClick.AddListener(() => Paint(colors[index]));
}Thử thách
DễKết nối bàn phím của két sắt trong Start().
- Duyệt qua
keysbằng vòng lặp (loop)for. Trong vòng lặp, khai báoint digit = i + 1;và kết nốikeys[i]với() => Press(digit). - Kết nối
clearButtonvới một lambda đặtentered = ""và gọiShowCode().
Nhấn Chơi rồi nhập 3, 1, 2: màn hình hiển thị Open. Sau đó nhấn Kiểm tra.
Tự làm thử
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();
// Gắn từng phím với Press và truyền chữ số tương ứng, rồi gắn clearButton với thao tác xóa 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;
}
}
Tất cả bài học trong Xây dựng trò chơi thực tế
1Văn bản trên màn hình
Canvas và văn bảnHiển thị điểm sốĐịnh dạng sốĐồng hồ đếm ngượcÔn tập: Đồng hồ tốc độ7Điều khiển thời gian
Tạm dừng bằng timeScaleChuyển động chậmThời gian không bị co giãnÔn tập: Bullet Time2Nút bấm và màn hình
Nút bấm và onClickLambdaKết nối trong InspectorBật và tắt bảngThanh máuÔn tập: Cửa hàng nâng cấp5Lưu dữ liệu với PlayerPrefs
Lưu một sốTải với giá trị mặc địnhĐiểm cao nhấtLưu cài đặtÔn tập: Tiền xu trong ngân hàngTự luyện tập: Playground Unity