람다 함수이란 마치 오브젝트를 탄생시키듯이 코드 도중에 이름이 없는 함수
를 만들고 마치 변수에 값을 넣어 주듯이 여기저기에 줄 수 있다.
형식
(input-parameters) => {expression;};
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Messenger : MonoBehaviour
{
public delegate void Send(string reciver);
Send onSend;
void SendMail(string reciever)
{
Debug.Log("Mail sent to: " + reciever);
}
void SendMoney(string reciever)
{
Debug.Log("Money sent to: " + reciever);
}
void Start()
{
onSend += SendMail;
onSend += SendMoney;
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
onSend("anso");
}
}
}
이렇게 작성하고 Unity에서 스페이스바를 누르면
Mail sent to: anso
와 Money sent to: anso
가 콘솔창에 실행된다.
하지만 이코드를 람다 함수로 바꾸면 어떻게 될까요?
void SendMail(string reciever)
{
Debug.Log("Mail sent to: " + reciever);
}
void SendMoney(string reciever)
{
Debug.Log("Money sent to: " + reciever);
}
위의 코드를
onSend += (reciever) => Debug.Log("Mail sent to: " + reciever);
onSend += (reciever) => Debug.Log("Mail sent to: " + reciever);
와 같이 바꿀수 있습니다.
메서드의 이름은 없으며 즉석에서 구현되는 함수.
reciever은 매개 변수이며 입력값이 한개이면 Type을 안붙여줘도 알아서 처리합니다.
void SendMail(string reciever)
{
Debug.Log("Mail sent to: " + reciever);
}
void SendMoney(string reciever)
{
Debug.Log("Money sent to: " + reciever);
}
위의 코드를
onSend += (reciever) =>
{
Debug.Log("Mail sent to: " + reciever);
Debug.Log("Money sent to: " + reciever);
}
//또는 위의 메서드를 그대로 사용해서
{
SendMail(reciever);
SendMoney(reciever);
}
이 처럼 바꿀수 있다.
using System;
namespace FuncTest
{
class MainApp
{
static void Main(string[] args)
{
// Func<TResult> : 입력 매개변수 없는 버전
Func<int> func1 = () => 10; // 입력 매개변수는 없으며, 무조건 10 반환
Console.WriteLine($"func1() : {func1()}");
// Func<T1, TResult> : 매개변수 1개
Func<int, int> func2 = (x) => x * 2; // 입력 매개변수는 int 형식 하나, 반환 형식도 int
Console.WriteLine($"func2(4) : {func2(4)}");
// Func<T1, T2, TResult> : 매개변수 2개
Func<double, double, double> func3 = (x, y) => x / y; // 입력 매개변수는 double 형식 둘, 반환 형식도 double
Console.WriteLine($"func3(22, 7) : {func3(22, 7)}");
}
}
}
using System;
namespace ActionTest
{
class MainApp
{
static void Main(string[] args)
{
// Action<T> : 매개변수 1개 버전
Action act1 = () => Console.WriteLine("Action()");
act1();
int result = 0;
Action<int> act2 = (x) => result = x * x; // result에 x * x 결과 저장
act2(3);
Console.WriteLine($"result : {result}");
// Action<T1, T2> : 매개변수 2개 버전
Action<double, double> act3 = (x, y) =>
{
double pi = x / y;
Console.WriteLine($"Action<T1, T2>({x}, {y}) : {pi}");
};
act3(22.0, 7.0);
}
}
}
Unity UIpopup을 작업할때 사용했던 코드 입니다.
//UIPopup.cs
using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class UIPopup : MonoBehaviour
{
[SerializeField] private TMP_Text txtTitle;
[SerializeField] private TMP_Text txtContent;
[SerializeField] private Button _btnBack;
[SerializeField] private Button _btnConform;
[SerializeField] private Button _btnCancel;
[SerializeField] private GameObject Popup;
private Action _onConfirm;
void Start()
{
_btnBack.onClick.AddListener(Close);
_btnCancel.onClick.AddListener(Close);
_btnConform.onClick.AddListener(Confirm);
}
public void SetPopup(string title, string content, Action onConfirm)
{
txtTitle.text = title;
txtContent.text = content;
_onConfirm = onConfirm;
}
void Confirm()
{
_onConfirm?.Invoke();
_onConfirm = null;
Close();
}
void Close()
{
Popup.SetActive(false);
}
}
// 다른 클래스 안
private UIPopup _uiPopup;
[SerializeField] private GameObject _SetName;
[SerializeField] private GameObject _Popup;
[SerializeField] private Button _btnNameConfirm;
private SetPlayerStatus _SetPlayerStatus;
private void Start()
{
_uiPopup = GetComponent<UIPopup>();
_SetPlayerStatus = GetComponent<SetPlayerStatus>();
_btnNameConfirm.onClick.AddListener(OpenPopup_SetPlayerName);
}
void OpenPopup_SetPlayerName()
{
_Popup.SetActive(true);
_uiPopup.SetPopup("확인", "정말 결정하시겠습니까?", SetPlayerName_Event);
}
void SetPlayerName_Event()
{
_SetPlayerStatus.SetPlayerName();
_SetName.SetActive(false);
_SetGmaeDifficulty.SetActive(true);
}
식 트리의 내용 너무 길고 복잡하기에 다음번에 이어서 작성하도록 하겠습니다.