유니티에서 함수를 대신해서 작동하게 하는 문법이 세가지 있다.
델리게이트 : 함수 포인터
Action : 리턴이 없는 값 (void 리턴)
Func : 리턴이 있는값 (값 리턴)
하나하나 살펴보자.
1. delegate
델리게이트는 함수의 포인터 즉, 대리자이다.
함수를 대신 실행해주는 역할을 한다.
정확히 안와닿지만, 일단 다음 예제를 보자.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test : MonoBehaviour
{
delegate void NumDelegate(int num);
NumDelegate del;
// Start is called before the first frame update
void Start()
{
del = FirstPlus;
del(10);
del = SecondPlus;
del(5);
}
void FirstPlus(int num){
int result = num * num;
Debug.Log("FirstPlus : " + result);
}
void SecondPlus(int num){
int result = num * num * num;
Debug.Log("SecondPlus : " + result);
}
}
위 코드에서는 델리게이트를 선언 한 뒤, 선언한 델리게이트로 변수를 만들어주고, Start에서 변수에 차례대로 함수 FirstPlus와 SecondPlus를 넣어주고 있다.
델리게이트에 넣을 땐, 반환형식과, 입력값의 수가 서로 동일한 함수만 넣을 수 있다. (위에서는 델리게이트가 void반환형에 int num 하나씩 받고 있기 때문에 델리게이트와 구조가 동일한 함수 FirstPlus, SecondPlus를 넣을 수 있는것이다.)
처음에는 FirstPlus가 들어갔으니 del에 10을 전달하면 Log에 100이 찍힐것이다.
그 다음엔 SecondPlus가 들어갔으니 del에 5를 전달하면 125가 찍힐것이다.
위 코드를 실행해보면 다음과 같이 출력된다.

예상 결과와 같이 잘 찍히고 있다.
그런데, 델리게이트를 선언하는 과정이 너무 길다고 느껴질 수 있고, 지금은 짧지만, 추후에 길어질 수도 있다.
우리는 델리게이트를 간편하게 쓰기 위해서 Action과, Func를 쓰는것이다. 각각 차례대로 살펴보자.
2. Action
Action은 델리게이트에서 반환형식이 없을 때 (void일 때) 사용한다.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test : MonoBehaviour
{
// delegate void NumDelegate(int num);
// NumDelegate del;
Action<int> del;
// Start is called before the first frame update
void Start()
{
del = FirstPlus;
del(10);
del = SecondPlus;
del(5);
}
void FirstPlus(int num){
int result = num * num;
Debug.Log("FirstPlus : " + result);
}
void SecondPlus(int num){
int result = num * num * num;
Debug.Log("SecondPlus : " + result);
}
}
(참고로, Action은 System아래에 선언되어있어서 using System을 작성해야한다.)
그래서 위와 같이 바꿔 쓸 수 있다. (물론 매개변수의 수를 맞춰줘야한다.)
위를 실행하면 전과 동일한 결과를 받을 수 있다.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test : MonoBehaviour
{
public Action OnStartClicked;
private void Start() {
OnStartClicked += Action1;
OnStartClicked += Action2;
OnStartClicked();
}
void Action1(){
print("Action1");
}
void Action2(){
print("Action2");
}
}
예제를 다르게 가져왔다.
여기서는 Action에서 사용할 함수들이 전부 매개변수가 없기 때문에 Action의 <>부분이 사라진걸 볼 수 있다.
Action의 가장 큰 특징이 여기서 보이게 되는데 바로 함수를 묶어서 사용 가능하다는 특징이 있다.
따라서, OnStartClicked에 += 연산을 사용해서 함수 Action1, Action2를 모두 등록을 해준다.
이후, OnStartClicked를 호출하면 다음과 같이 실행된다.

이렇게 한번 호출을 해도 두 함수가 차례대로 실행되고 있는것을 볼 수 있다.
이런식으로 += 연산을 사용해 함수를 등록하는 과정을 델리게이트 체인이라고 한다.
함수들이 사슬같이 연결되어있다고 해서 이렇게 부른다.
델리게이트 체인을 사용하는 이유중 하나가, 위와 같이 스크립트 내부에 함수가 선언되어있지 않아도, 외부 스크립트에서 Action에 등록만 해준다면, 함수를 실행할 수 있기 때문이다. 아래의 예제를 확인하자.

일단, 앞서 사용하던 Test스크립트 말고, Test2, Test3스크립트를 더 생성해주고 각각 오브젝트에 넣어줬다.

그래서 지금은 이런 상태다. 이런 상태로 만들어 둔 후 진행해보자.
//Test.cs
public class Test : MonoBehaviour
{
public Action OnStartClicked;
private void Start() {
OnStartClicked();
}
}
//Test2.cs
public class Test2 : MonoBehaviour
{
[SerializeField] Test test;
// Start is called before the first frame update
void Start()
{
test.OnStartClicked += OnStartClicked;
}
void OnStartClicked(){
print("Test2에서 실행됨.");
}
}
//Test3.cs
public class Test3 : MonoBehaviour
{
[SerializeField] Test test;
// Start is called before the first frame update
void Start()
{
test.OnStartClicked += OnStartClicked;
}
void OnStartClicked(){
print("Test3에서 실행됨.");
}
}
각 스크립트에 위와 같이 작성해주자. 내용은 동일하나, OnStartClicked에서 실행되는 log의 문구가 각각 다르다.
코드에 대해 설명하자면, Test를 받아와서, 그 안에 있는 OnStartClicked Action에 각 스크립트에서 선언된 함수를 등록시켜줬다.
위와 같이 구성해주면, Test스크립트는 굉장히 깔끔해진걸 볼 수 있다.
저장해둔 뒤,

Test2, Test3에 Test를 할당시켜주자.
이후, 실행해보면

Test2, 3 스크립트 모두에서 실행된걸 볼 수 있다.
그래서 아래와 같이
public class Test : MonoBehaviour
{
public Action OnStartClicked;
private void Start() {
OnStartClicked();
}
}
지금은 start에서 실행되도록 했지만, 예를 들어 게임 플레이 중, 게임오버 할 때, 필요한 모든 함수들을 구독해서 Action 변수를 호출한다면 한번에 실행되도록 만들 수 있다.
그리고, 만약, OnStartClicked에 구독(연결)되어있는 함수가 하나도 없다면? (직접 Test2, Test3에서 구독하는 부분을 주석처리 하고 실행해보자)

이렇게 오류가 발생하게 된다.
이를 방지하기 위해 (구독이 하나도 안되어있을 경우, 실행되는것을 방지하기 위해) Test스크립트를 다음과 같이 수정하자.
public class Test : MonoBehaviour
{
public Action OnStartClicked;
private void Start() {
OnStartClicked?.Invoke();
}
}
이렇게 수정했다.
OnstartClicked?.Invoke();에서, ?. 부분이 OnStartClicked가 null상태인지 체크하는 부분이다. null이 아니라면 Invoke를 사용해서 함수를 실행하는것이다.
혹은 ?로 null체크를 하기 싫을 경우는 다음과 같이 작성할 수 있다.
public class Test : MonoBehaviour
{
public Action OnStartClicked = () => { };
private void Start() {
OnStartClicked.Invoke();
}
}
바로 OnStartClicked에 빈 껍데기인 람다식을 거는것이다.
이렇게 하면 OnStartClicked가 null이 아닌, 빈 껍데기 함수가 등록된걸로 처리하기 때문에, 결론적으로 동일한 결과가 도출된다.
지금 Test스크립트 상태에서는 다음과 같은 작업이 가능하다.
//Test2.cs
public class Test2 : MonoBehaviour
{
[SerializeField] Test test;
void Start()
{
test.OnStartClicked = OnStartClicked;
test.OnStartClicked();
//위와 같은 코드
//test.OnStartClicked?.Invoke();
}
void OnStartClicked(){
print("Test2에서 실행됨.");
}
}
Action이 선언된 스크립트가 아닌, 다른 스크립트에서 Action에 직접적인 대입과 호출이 가능하게 된다.
이를 막아주려면 Test스크립트를 다음과 같이 수정하자.
public class Test : MonoBehaviour
{
public event Action OnStartClicked;
private void Start() {
OnStartClicked?.Invoke();
}
}
Action 이전에 event키워드를 붙여주었다.
그러면 다음과 같이 변하게 된다.

직접적인 대입과, 호출 연산이 불가능하게 되었다.
물론 event가 선언되어있는 Test스크립트 내부에선 대입, 호출 전부 가능하다. (다른 스크립트에서 하지 못하도록 막아둔것이다.)
그리고 보통 += 으로 추가만 해주는것이 아니라, -=를 사용해 삭제도 해주어야한다.
public class Test2 : MonoBehaviour
{
[SerializeField] Test test;
void Start()
{
test.OnStartClicked += OnStartClicked;
}
private void OnDestroy() {
test.OnStartClicked -= OnStartClicked;
}
void OnStartClicked(){
print("Test2에서 실행됨.");
}
}
이런식으로, 스크립트가 파괴되었을 때, 이벤트를 구독취소해줘야한다. (물론 생명주기에 따라서 Start가 아닌 OnEnable에 해줘도 상관 없다. 생명주기를 잘 생각해서 작성하자.)
왜냐면, 스크립트가 파괴되어도 Action이 계속 함수를 가지고 있을 수 있기 때문이다.
그리고 Test스크립트가 하나만 있다는게 보장이 된다면 Action을 선언할 때
public static event Action OnStartClicked;
이런식으로 선언하여 Test.OnStartClicked로 바로 쓸 수 있도록 만들어줘도 된다.
3. Func
Action과 반대로 반환형이 있는 함수의 구독을 위한 키워드이다.
다음과 같이 선언해 사용한다.
public Func<int> OnStartClicked;
<> 를 잘 보면, int가 들어가있는데 항상 마지막 자료형은 반환형식이다.
예를 들어 <int, int, string> 이라면 string이 반환형식이 되고, <int, float, int>라면 int가 반환형식이 된다.
또한 <int> 이런식으로 하나만 존재한다면, 입력값이 없고 반환형식만 존재하는 형태가 된다.
Test를 예시로 살펴보자.
public class Test : MonoBehaviour
{
public Func<int> OnStartClicked;
private void Start() {
OnStartClicked += Add;
int i = OnStartClicked();
}
int Add()
{
return 0;
}
}
이런식으로 사용하면 된다.
추가로, 입력값이 여러개인 함수인 경우를 살펴보자.
public class Test : MonoBehaviour
{
public Func<int,int,int> OnStartClicked;
private void Start() {
OnStartClicked += Add;
int i = OnStartClicked(3, 4);
print(i);
}
int Add(int num1, int num2)
{
return num1 + num2;
}
}
<>안의 입력값, 반환형태를 잘 맞춰주고, 함수를 구독시켜 실행해보자.

7이 잘 출력된것을 볼 수 있다.
그럼 이런 형태라면 어떻게 될까?
public class Test : MonoBehaviour
{
public Func<int,int,int> OnStartClicked;
private void Start() {
OnStartClicked += Add;
OnStartClicked += Sub;
int i = OnStartClicked(3, 4);
print(i);
}
int Add(int num1, int num2)
{
print("Add실행");
return num1 + num2;
}
int Sub(int num1, int num2)
{
print("Sub실행");
return num1 - num2;
}
}

함수가 차례대로 실행되지만, Add를 받았을 시점에는 따로 저장해두는것이 없어 다음 함수의 실행으로 넘어가게 된다.
따라서 i는 -1이 되는것이다.
Func는 델리게이트 체인을 만들기 위해서 실행한다기 보단, 특정 함수를 빠르게 실행하기 위해서 사용한다.
public Func<int, int, int> OnStartClicked = (num1, num2) => { return num1 + num2; };
와 같이 람다식을 활용해 함수를 선언해둔 뒤 빠르게 실행하기 위해서 사용한다.
또한, 아까와 같이 static을 사용할 수 있는 조건과 맞다면 static을 사용할 수 있다.
public static Func<int,int,int> OnStartClicked = (num1, num2) => { return num1 + num2; };
//사용할 땐
Test.OnStartClicked(3,4);
Event는 우리가 클래스의 큰 구조를 설계하다보면 서로가 서로를 참조하는 과정을 막는데 공헌하는 역할을 한다.
물론 너무 남용하면 안되고 적당히 효율적일것 같을 때 사용하면 강력한 무기가 될 수 있다.
더 자세한 내용은 아래의 영상을 참고하자.
'Develop > Unity' 카테고리의 다른 글
[Unity] 이벤트의 구현을 지원하는 Signaler를 사용해보자! (echo17.Signaler) (0) | 2024.11.16 |
---|---|
[Unity] Hierarchy를 정리해보자 (Hierarchy Designer) (0) | 2024.11.04 |
[Unity] 유니티에서 라디오버튼 구현하기 (Unity RadioButton) (0) | 2024.07.22 |
[Unity] 씬을 전환할 때 로딩을 걸어보자 - 씬 비동기 로딩, 로딩창 구현 (0) | 2024.07.03 |
[Unity] 회원가입 시 주소 입력이 필요할때 (우편코드 및 도로명주소) - 행정안전부 도로명주소 api (0) | 2024.07.02 |
유니티에서 함수를 대신해서 작동하게 하는 문법이 세가지 있다.
델리게이트 : 함수 포인터
Action : 리턴이 없는 값 (void 리턴)
Func : 리턴이 있는값 (값 리턴)
하나하나 살펴보자.
1. delegate
델리게이트는 함수의 포인터 즉, 대리자이다.
함수를 대신 실행해주는 역할을 한다.
정확히 안와닿지만, 일단 다음 예제를 보자.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test : MonoBehaviour
{
delegate void NumDelegate(int num);
NumDelegate del;
// Start is called before the first frame update
void Start()
{
del = FirstPlus;
del(10);
del = SecondPlus;
del(5);
}
void FirstPlus(int num){
int result = num * num;
Debug.Log("FirstPlus : " + result);
}
void SecondPlus(int num){
int result = num * num * num;
Debug.Log("SecondPlus : " + result);
}
}
위 코드에서는 델리게이트를 선언 한 뒤, 선언한 델리게이트로 변수를 만들어주고, Start에서 변수에 차례대로 함수 FirstPlus와 SecondPlus를 넣어주고 있다.
델리게이트에 넣을 땐, 반환형식과, 입력값의 수가 서로 동일한 함수만 넣을 수 있다. (위에서는 델리게이트가 void반환형에 int num 하나씩 받고 있기 때문에 델리게이트와 구조가 동일한 함수 FirstPlus, SecondPlus를 넣을 수 있는것이다.)
처음에는 FirstPlus가 들어갔으니 del에 10을 전달하면 Log에 100이 찍힐것이다.
그 다음엔 SecondPlus가 들어갔으니 del에 5를 전달하면 125가 찍힐것이다.
위 코드를 실행해보면 다음과 같이 출력된다.

예상 결과와 같이 잘 찍히고 있다.
그런데, 델리게이트를 선언하는 과정이 너무 길다고 느껴질 수 있고, 지금은 짧지만, 추후에 길어질 수도 있다.
우리는 델리게이트를 간편하게 쓰기 위해서 Action과, Func를 쓰는것이다. 각각 차례대로 살펴보자.
2. Action
Action은 델리게이트에서 반환형식이 없을 때 (void일 때) 사용한다.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test : MonoBehaviour
{
// delegate void NumDelegate(int num);
// NumDelegate del;
Action<int> del;
// Start is called before the first frame update
void Start()
{
del = FirstPlus;
del(10);
del = SecondPlus;
del(5);
}
void FirstPlus(int num){
int result = num * num;
Debug.Log("FirstPlus : " + result);
}
void SecondPlus(int num){
int result = num * num * num;
Debug.Log("SecondPlus : " + result);
}
}
(참고로, Action은 System아래에 선언되어있어서 using System을 작성해야한다.)
그래서 위와 같이 바꿔 쓸 수 있다. (물론 매개변수의 수를 맞춰줘야한다.)
위를 실행하면 전과 동일한 결과를 받을 수 있다.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test : MonoBehaviour
{
public Action OnStartClicked;
private void Start() {
OnStartClicked += Action1;
OnStartClicked += Action2;
OnStartClicked();
}
void Action1(){
print("Action1");
}
void Action2(){
print("Action2");
}
}
예제를 다르게 가져왔다.
여기서는 Action에서 사용할 함수들이 전부 매개변수가 없기 때문에 Action의 <>부분이 사라진걸 볼 수 있다.
Action의 가장 큰 특징이 여기서 보이게 되는데 바로 함수를 묶어서 사용 가능하다는 특징이 있다.
따라서, OnStartClicked에 += 연산을 사용해서 함수 Action1, Action2를 모두 등록을 해준다.
이후, OnStartClicked를 호출하면 다음과 같이 실행된다.

이렇게 한번 호출을 해도 두 함수가 차례대로 실행되고 있는것을 볼 수 있다.
이런식으로 += 연산을 사용해 함수를 등록하는 과정을 델리게이트 체인이라고 한다.
함수들이 사슬같이 연결되어있다고 해서 이렇게 부른다.
델리게이트 체인을 사용하는 이유중 하나가, 위와 같이 스크립트 내부에 함수가 선언되어있지 않아도, 외부 스크립트에서 Action에 등록만 해준다면, 함수를 실행할 수 있기 때문이다. 아래의 예제를 확인하자.

일단, 앞서 사용하던 Test스크립트 말고, Test2, Test3스크립트를 더 생성해주고 각각 오브젝트에 넣어줬다.

그래서 지금은 이런 상태다. 이런 상태로 만들어 둔 후 진행해보자.
//Test.cs
public class Test : MonoBehaviour
{
public Action OnStartClicked;
private void Start() {
OnStartClicked();
}
}
//Test2.cs
public class Test2 : MonoBehaviour
{
[SerializeField] Test test;
// Start is called before the first frame update
void Start()
{
test.OnStartClicked += OnStartClicked;
}
void OnStartClicked(){
print("Test2에서 실행됨.");
}
}
//Test3.cs
public class Test3 : MonoBehaviour
{
[SerializeField] Test test;
// Start is called before the first frame update
void Start()
{
test.OnStartClicked += OnStartClicked;
}
void OnStartClicked(){
print("Test3에서 실행됨.");
}
}
각 스크립트에 위와 같이 작성해주자. 내용은 동일하나, OnStartClicked에서 실행되는 log의 문구가 각각 다르다.
코드에 대해 설명하자면, Test를 받아와서, 그 안에 있는 OnStartClicked Action에 각 스크립트에서 선언된 함수를 등록시켜줬다.
위와 같이 구성해주면, Test스크립트는 굉장히 깔끔해진걸 볼 수 있다.
저장해둔 뒤,

Test2, Test3에 Test를 할당시켜주자.
이후, 실행해보면

Test2, 3 스크립트 모두에서 실행된걸 볼 수 있다.
그래서 아래와 같이
public class Test : MonoBehaviour
{
public Action OnStartClicked;
private void Start() {
OnStartClicked();
}
}
지금은 start에서 실행되도록 했지만, 예를 들어 게임 플레이 중, 게임오버 할 때, 필요한 모든 함수들을 구독해서 Action 변수를 호출한다면 한번에 실행되도록 만들 수 있다.
그리고, 만약, OnStartClicked에 구독(연결)되어있는 함수가 하나도 없다면? (직접 Test2, Test3에서 구독하는 부분을 주석처리 하고 실행해보자)

이렇게 오류가 발생하게 된다.
이를 방지하기 위해 (구독이 하나도 안되어있을 경우, 실행되는것을 방지하기 위해) Test스크립트를 다음과 같이 수정하자.
public class Test : MonoBehaviour
{
public Action OnStartClicked;
private void Start() {
OnStartClicked?.Invoke();
}
}
이렇게 수정했다.
OnstartClicked?.Invoke();에서, ?. 부분이 OnStartClicked가 null상태인지 체크하는 부분이다. null이 아니라면 Invoke를 사용해서 함수를 실행하는것이다.
혹은 ?로 null체크를 하기 싫을 경우는 다음과 같이 작성할 수 있다.
public class Test : MonoBehaviour
{
public Action OnStartClicked = () => { };
private void Start() {
OnStartClicked.Invoke();
}
}
바로 OnStartClicked에 빈 껍데기인 람다식을 거는것이다.
이렇게 하면 OnStartClicked가 null이 아닌, 빈 껍데기 함수가 등록된걸로 처리하기 때문에, 결론적으로 동일한 결과가 도출된다.
지금 Test스크립트 상태에서는 다음과 같은 작업이 가능하다.
//Test2.cs
public class Test2 : MonoBehaviour
{
[SerializeField] Test test;
void Start()
{
test.OnStartClicked = OnStartClicked;
test.OnStartClicked();
//위와 같은 코드
//test.OnStartClicked?.Invoke();
}
void OnStartClicked(){
print("Test2에서 실행됨.");
}
}
Action이 선언된 스크립트가 아닌, 다른 스크립트에서 Action에 직접적인 대입과 호출이 가능하게 된다.
이를 막아주려면 Test스크립트를 다음과 같이 수정하자.
public class Test : MonoBehaviour
{
public event Action OnStartClicked;
private void Start() {
OnStartClicked?.Invoke();
}
}
Action 이전에 event키워드를 붙여주었다.
그러면 다음과 같이 변하게 된다.

직접적인 대입과, 호출 연산이 불가능하게 되었다.
물론 event가 선언되어있는 Test스크립트 내부에선 대입, 호출 전부 가능하다. (다른 스크립트에서 하지 못하도록 막아둔것이다.)
그리고 보통 += 으로 추가만 해주는것이 아니라, -=를 사용해 삭제도 해주어야한다.
public class Test2 : MonoBehaviour
{
[SerializeField] Test test;
void Start()
{
test.OnStartClicked += OnStartClicked;
}
private void OnDestroy() {
test.OnStartClicked -= OnStartClicked;
}
void OnStartClicked(){
print("Test2에서 실행됨.");
}
}
이런식으로, 스크립트가 파괴되었을 때, 이벤트를 구독취소해줘야한다. (물론 생명주기에 따라서 Start가 아닌 OnEnable에 해줘도 상관 없다. 생명주기를 잘 생각해서 작성하자.)
왜냐면, 스크립트가 파괴되어도 Action이 계속 함수를 가지고 있을 수 있기 때문이다.
그리고 Test스크립트가 하나만 있다는게 보장이 된다면 Action을 선언할 때
public static event Action OnStartClicked;
이런식으로 선언하여 Test.OnStartClicked로 바로 쓸 수 있도록 만들어줘도 된다.
3. Func
Action과 반대로 반환형이 있는 함수의 구독을 위한 키워드이다.
다음과 같이 선언해 사용한다.
public Func<int> OnStartClicked;
<> 를 잘 보면, int가 들어가있는데 항상 마지막 자료형은 반환형식이다.
예를 들어 <int, int, string> 이라면 string이 반환형식이 되고, <int, float, int>라면 int가 반환형식이 된다.
또한 <int> 이런식으로 하나만 존재한다면, 입력값이 없고 반환형식만 존재하는 형태가 된다.
Test를 예시로 살펴보자.
public class Test : MonoBehaviour
{
public Func<int> OnStartClicked;
private void Start() {
OnStartClicked += Add;
int i = OnStartClicked();
}
int Add()
{
return 0;
}
}
이런식으로 사용하면 된다.
추가로, 입력값이 여러개인 함수인 경우를 살펴보자.
public class Test : MonoBehaviour
{
public Func<int,int,int> OnStartClicked;
private void Start() {
OnStartClicked += Add;
int i = OnStartClicked(3, 4);
print(i);
}
int Add(int num1, int num2)
{
return num1 + num2;
}
}
<>안의 입력값, 반환형태를 잘 맞춰주고, 함수를 구독시켜 실행해보자.

7이 잘 출력된것을 볼 수 있다.
그럼 이런 형태라면 어떻게 될까?
public class Test : MonoBehaviour
{
public Func<int,int,int> OnStartClicked;
private void Start() {
OnStartClicked += Add;
OnStartClicked += Sub;
int i = OnStartClicked(3, 4);
print(i);
}
int Add(int num1, int num2)
{
print("Add실행");
return num1 + num2;
}
int Sub(int num1, int num2)
{
print("Sub실행");
return num1 - num2;
}
}

함수가 차례대로 실행되지만, Add를 받았을 시점에는 따로 저장해두는것이 없어 다음 함수의 실행으로 넘어가게 된다.
따라서 i는 -1이 되는것이다.
Func는 델리게이트 체인을 만들기 위해서 실행한다기 보단, 특정 함수를 빠르게 실행하기 위해서 사용한다.
public Func<int, int, int> OnStartClicked = (num1, num2) => { return num1 + num2; };
와 같이 람다식을 활용해 함수를 선언해둔 뒤 빠르게 실행하기 위해서 사용한다.
또한, 아까와 같이 static을 사용할 수 있는 조건과 맞다면 static을 사용할 수 있다.
public static Func<int,int,int> OnStartClicked = (num1, num2) => { return num1 + num2; };
//사용할 땐
Test.OnStartClicked(3,4);
Event는 우리가 클래스의 큰 구조를 설계하다보면 서로가 서로를 참조하는 과정을 막는데 공헌하는 역할을 한다.
물론 너무 남용하면 안되고 적당히 효율적일것 같을 때 사용하면 강력한 무기가 될 수 있다.
더 자세한 내용은 아래의 영상을 참고하자.
'Develop > Unity' 카테고리의 다른 글
[Unity] 이벤트의 구현을 지원하는 Signaler를 사용해보자! (echo17.Signaler) (0) | 2024.11.16 |
---|---|
[Unity] Hierarchy를 정리해보자 (Hierarchy Designer) (0) | 2024.11.04 |
[Unity] 유니티에서 라디오버튼 구현하기 (Unity RadioButton) (0) | 2024.07.22 |
[Unity] 씬을 전환할 때 로딩을 걸어보자 - 씬 비동기 로딩, 로딩창 구현 (0) | 2024.07.03 |
[Unity] 회원가입 시 주소 입력이 필요할때 (우편코드 및 도로명주소) - 행정안전부 도로명주소 api (0) | 2024.07.02 |