1. 오늘의 학습
델리케이트와 람다에 대해 학습했다.
델리케이트의 연장선인 Action과 Function도 학습했다.
Action은 저번에 쓴 게 비슷한 것 같은데....(event Action과 다른 걸까?)
간단해 정리해보자 Let's go
2. 학습 정리📘
Action을 들어가고 싶지만 그 전에 델리케이트를 정리한다.
1. 델리케이트(Delegate)
(솔직히 Dedicated로 들었다.)
함수를 변수처럼 다룰 수 있으면 좋겠다~ 아 있을 것 같은데~했는데….
이게 진짜 있네. 의 주인공이다.
그 전에 알고 있던 건 돌아다니면서 겨우 주워먹은 event Action뿐이라 헤에 그렇구나 하고 그냥 가져다 썼는데 이번 기회에 확실히 습득할 수 있어서 기쁘다.
Delegate. 위에 말했듯 함수, 메서드를 '변수'처럼 다룰 수 있게 해주는 코드이다.
Delegate에다가 함수 자체를 변수로 저장하고 출력 가능.
어떻게?
이렇게.
//접근제한자+delegate+반환형+델리게이트명();
public delegate void DeliTest();
public DeliTest deliTest;
public void DebugCode()
{
Debug.Log("테스트 코드 ON");
}
public void ShowDebug()
{
deliTest = DebugCode;
deliTest?.Invoke();
}
그리고 ShowDebug를 Start()에서 실행하면 DebugCode()의 내용이 그대로 출력된다.
매개변수가 들어가면 똑같이 매개변수를 추가해주면 된다.
?.Invoke는 해당 함수가 null값을 반환해도 처리할 수 있도록 해둔 안전장치이다.
그리고 이걸 더 간단하게 한 버전이 있다.
2. Action, Func
사용방법은 델리게이트보다 더 쉽다.
기존 델리게이트의 2줄짜리 선언을
public Action actionTest;
로 바꾸면 끝난다.
그리고 actionTest = DebugCode; 로 할당만 해주면 나머지는 끝.
델리게이트보다 더 쉽고 간단하게 함수를 변수로 바꿀 수 있다.
하지만 Action은 기본적으로 void일 때만 사용할 수 있고, 반환형이 그 외의 것이라면 Func를 사용한다.
사용법은 거의 같지만, Func는 return int, string등을 반환할 수 있다.
3. Action과 event Action의 차이
그런데 내가 개판냥판을 만들 때 썼던 건 event Action이었다. 구조는 거의 같은 것 같았는데.
event키워드가 더 붙었는데 뭔가 다른가?
역시 다르겠지? 코딩인데 괜히 하나가 더 붙은 채 기능한 게 아닐테니까?
바로 찾아보자.
event Action은 Action 타입에 C# event 키워드를 붙인 것이다.
이 키워드를 통해 해당 Delegate에 대한 접근을 제한, 외부에서는 이벤트를 '구독(+=)'과 '구독 취소(-=)'만 가능하게 만들어준다.
이벤트 자체를 직접 호출하거나 =null로 초기화 하는 것은 선언된 클래스 내부에서만 가능하다.
아래는 개판냥판에서 사용했던 Item.cs의 일부이다.
//이벤트 시스템으로 Fish와 Bone의 카운트 변화가 있을 때마다 호출
public static event Action OnItemCountChanged;
private void Awake()
{
//Fish, Bone 오브젝트 아래에 있는 자식들(Fish 클론들) 카운트)
BoneCount = BoneObj.transform.childCount;
FishCount = FishObj.transform.childCount;
OnItemCountChanged?.Invoke();
}
public static void ChangeFishCount(int delta)
{
FishCount += delta;
OnItemCountChanged?.Invoke();
}
public static void ChangeBoneCount(int delta)
{
BoneCount += delta;
OnItemCountChanged?.Invoke();
}
그리고 해당 요소를 구독/구독 취소한 곳은 ItemCountUI.cs로, 여기서는 구독(+=)과 구독취소(-=)밖에 하지 못했다.
여기서 직접 OnItemCountChanged?.Invoke();는 사용할 수 없는 것이다.
하지만 Action은 클래스 내부 뿐만이 아니라 외부에서도 호출이 가능하다.
할당 및 초기화도 Action은 외부에서도 가능하지만 event Action은 불가능하다.
하지만 함수를 할당하는 것은 둘 다 외부와 내부 모두 가능하다.
즉 둘의 차이
: event Action = 내부에서만 호출가능. 특정 사건 발생 시 알림 시스템 (OnEnable과 OnDisable을 통해 구독관리)
Action = 외부에서도 호출 가능. 임시 이벤트 처리나 간단한 함수 콜백 등 유연하게 메소드를 가져오고 싶을 때 사용.
event Action은 이벤트가 터질 때마다 중복으로 적용되는 걸 방지하기 위해 OnEnable과 OnDisable을 잘 이용해주는 게 좋다.
4. 람다
=>로 익숙한 것.
일종에 이름 없는 함수를 만드는 형태이다. (함수 식조차 쓰기 귀찮은 자들의...)
장점: 단순하고 가독성이 좋으며 가볍게 쓰기 좋다.
단점: 길어지면 가독성을 오히려 해치므로 따로 함수로 뺄 것.
보통의 사용 처: 임시로 간단한 기능을 수행하는 함수가 필요할 때 사용 (대충 한줄 짜리..)
LINQ에서 많이 쓴다.
Action simpleLambda = () => Console.WriteLine("매개변수 없는 람다 식.");
정말 이거면 되는거야? 싶지만 정말 이거면 되는게 람다.
여기다가 이제 simpleLambda(); 나 simpleLambda.Invoke();를 쓰면 출력으로 매개변수 없는 람다식.이 나온다.
우와 중괄호도 없어!! 한줄이면 끝나!!!
물론 수식이 여러개면 { } 중괄호를 쓰면 된다. 이건 일반 함수랑 똑같다.
매개 변수가 있는 경우, 아래처럼 만들 수 있다.
Func<int, int> square = x => x*x;
square라는 이름의 Func식을 람다로 짧게 만든 것이다.
※ Func 식은 기본적으로 void형 델리게이트인 Action과 비슷하지만 반환값이 있는 메서드를 델리게이트 할때 사용한다. 그렇기에 뒤에 <매개변수, 반환값>의 형태를 가지는데, 매개변수가 여러개라도, 없더라도, 마지막은 무조건 반환값이다.
매개변수 int x를 받아서 x*x를 리턴하는 형태이다.
주의
: return 해야할 것이 너무 많거나, 복잡해지면 디버깅도 힘들어진다. 복잡하면 일반 메서드로 분리할 것. 잘 쓸 수 있으면 좋지만 못쓰겠으면 일단 일반 메서드나 잘 쓸 것.
3. 마무리
사실 이 TIL의 주요 내용은 event Action과 Action의 차이를 구분하는 것이었다.
이러나저러나 델리게이트는 상당히 유용해보이므로 앞으로 잘 쓸 수 있도록 해봐야겠다.
'Unity_본캠프' 카테고리의 다른 글
[내일배움캠프 25일차] Oh, Event. (2) | 2025.05.13 |
---|---|
[내일배움캠프 24일차] 생각보다 길은 단순함에 있다 (1) | 2025.05.12 |
[내일배움캠프 23일차] Unity팀 프로젝트: 트랩 / 클리어용 아이템 (0) | 2025.05.09 |
[내일배움캠프 22일차] 뭐라고요 string이 반환이 된다고 (0) | 2025.05.08 |
[내일배움캠프 21일차] 유니티 입문 특강 개인프로젝트 (0) | 2025.05.07 |