1. 델리게이트란?
델리게이트는 함수 포인터 역할을 수행하는 C#의 참조 타입이다.
다른 함수를 참조할 수 있는 변수처럼 사용되며, 함수를 대신해서 작동하게 한다.
1.1. 델리게이트의 사용
- 함수의 이름과 매개 변수를 지정하여 객체를 생성
- 한 함수에서 다른 함수로 동적 변경이 가능
- 입력 파라미터에 따라 결과가 출력되며, 로그를 통해 출력값을 확인 가능
ex)
간단한 계산함수
public class DelegateExample : MonoBehaviour
{
// 델리게이트 선언
private delegate int CalculateDelegate(int a, int b);
private CalculateDelegate calculateOperation;
// 할당할 함수
private int Add(int a, int b) => a + b;
private int Multiply(int a, int b) => a * b;
void Start()
{
// 델리게이트에 함수 할당
calculateOperation = Add;
Debug.Log($"덧셈 결과: {calculateOperation(5, 3)}");
// 다른 함수로 변경
calculateOperation = Multiply;
Debug.Log($"곱셈 결과: {calculateOperation(5, 3)}");
}
}
2. 액션(Action)이란?
입력과 출력이 없는 메서드를 가리키는 델리게이트의 간소화된 형태이다.
매개변수를 void로 설정 가능하며, 다양한 호출 결과를 다룰 수 있다.

2.1. 액션의 사용
- += 연산자를 사용하여 메서드를 등록
- 등록된 메서드는 원하는 시점에 반복 실행 가능
- 매개변수가 없는 경우 꺽쇠 괄호를 생략
- 여러 함수를 연달아 호출 가능
ex)
게임 시작/일시정지 이벤트, 점수시스템 연동
public class GameManager : MonoBehaviour
{
// 게임 상태 변경 이벤트
public static Action onGameStart;
public static Action<int> onScoreChanged; // 매개변수가 있는 Action
private int currentScore = 0;
void Start()
{
// 이벤트 리스너 등록
onGameStart += StartGame;
onScoreChanged += UpdateScoreUI;
}
void OnDestroy()
{
// 이벤트 리스너 제거
onGameStart -= StartGame;
onScoreChanged -= UpdateScoreUI;
}
public void StartGameButton()
{
// 이벤트 발생
onGameStart?.Invoke();
}
public void AddScore(int points)
{
currentScore += points;
onScoreChanged?.Invoke(currentScore);
}
private void StartGame()
{
// 게임 시작 로직
}
private void UpdateScoreUI(int newScore)
{
Debug.Log($"점수 : {newScore}점");
}
}
3. 이벤트(Event) 시스템
event 키워드를 사용하여 델리게이트를 선언한다.
클래스 외부에서의 델리게이트 선언을 제한한다.
3.1. 이벤트의 사용
- 연쇄 동작을 이끌어내는 트리거 역할
- 이벤트 발생 시 구독 중인 처리들이 연쇄적으로 실행
- 이벤트와 이벤트 리스너로 오브젝트 구분
ex)
UI시스템 연동, 메시지 표시 시스템, 인벤토리 UI 토글
public class UIManager : MonoBehaviour
{
// event 키워드를 사용하여 선언
private event Action<string> OnMessageReceived;
public event Action<bool> OnInventoryStateChanged;
// 이벤트 발생을 위한 메서드
private void RaiseMessageEvent(string message)
{
OnMessageReceived?.Invoke(message);
}
void Start()
{
OnMessageReceived += DisplayMessage;
OnInventoryStateChanged += ShowHideInventory;
}
public void ButtonClickHandler()
{
RaiseMessageEvent("버튼이 클릭되었습니다!");
}
public void InventoryButtonHandler(bool show)
{
OnInventoryStateChanged?.Invoke(show);
}
private void DisplayMessage(string message)
{
Debug.Log($"메시지 표시: {message}");
}
private void ShowHideInventory(bool show)
{
Debug.Log(show ? "인벤토리 열기" : "인벤토리 닫기");
}
void OnDestroy()
{
OnMessageReceived -= DisplayMessage;
OnInventoryStateChanged -= ShowHideInventory;
}
}
// event 사용 예시
public class GameController : MonoBehaviour
{
[SerializeField]
private UIManager uiManager;
void Start()
{
// event는 클래스 외부에서 구독만 가능
uiManager.OnInventoryStateChanged += HandleInventoryState;
// 아래 코드는 컴파일 에러 발생 - event는 외부에서 직접 호출 불가
uiManager.OnInventoryStateChanged.Invoke(true);
}
private void HandleInventoryState(bool isOpen)
{
Debug.Log($"인벤토리 상태 변경 감지: {isOpen}");
}
void OnDestroy()
{
if (uiManager != null)
{
uiManager.OnInventoryStateChanged -= HandleInventoryState;
}
}
}
4. 비교
Delegate
- 가장 기본적인 형태로 event와 Action의 기반
- 외부에서 직접 호출, 할당 가능
Action
- .NET에서 미리 정의된 delegate 타입
- 반환값이 없는 void 타입의 메서드만 참조 가능
- delegate를 직접 선언할 필요 없이 바로 사용가능
Event
- delegate 기반으로 캡슐화를 통해 안전한 이벤트 처리
- 외부에서는 구독/구독취소만 가능
특징 | Delegate | Action | Event |
선언 필요 | O | X | O |
외부 직접 호출 | O | O | X |
외부 직접 할당 | O | O | X |
캡슐화 | X | X | O |
용도 | 메서드 참조 타입 정의 | 안전한 이벤트 처리 | 간단한 콜백 처리 |
'Unity' 카테고리의 다른 글
벡터 (0) | 2024.11.01 |
---|---|
Null 관련 연산자 (3) | 2024.10.31 |
비동기 프로그래밍 (0) | 2024.09.08 |
Rigidbody.velocity 천천히 떨어지는 문제 (0) | 2024.04.21 |