C#에서 델리게이트를 이용하여 이벤트를 만들어 사용했습니다.
델리게이트는 함수를 변수처럼 저장해서 나중에 실행할 수 있는 기능이었죠.
델리게이트를 이용한 이벤트의 경우 특정 상황에서 특정 메서드를 호출할 수 있도록 했었습니다.
public class Player
{
// 델리게이트 타입 정의
public delegate void OnDeathHandler();
// 이벤트 선언
public static event OnDeathHandler OnDeath;
public void Die()
{
Debug.Log("플레이어 사망");
OnDeath?.Invoke(); // 이벤트 호출 (?.Invoke()는 null 체크 후 실행하는 안전한 호출방법)
}
}
public class GameManager : MonoBehaviour
{
private void OnEnable()
{
Player.OnDeath += GameOver; // +=는 이벤트에 함수 등록
}
private void OnDisable()
{
Player.OnDeath -= GameOver; // -=는 이벤트에서 함수 제거
}
void GameOver()
{
Debug.Log("게임 오버");
}
}
유니티에서는 C# 문법을 사용하기 때문에 델리게이트 이벤트도 사용할 수 있지만
유니티 자체의 이벤트 기능이 있습니다.
using UnityEngine;
using UnityEngine.Events;
public class ButtonClicker : MonoBehaviour
{
public UnityEvent onClick; // 인스펙터에서 연결 가능
public void Click()
{
Debug.Log("버튼 클릭됨");
onClick.Invoke(); // 연결된 함수들 호출
}
}
유니티 이벤트는 델리게이트 이벤트와 달리 +=, -= 와 같이 연산으로 추가하지 않습니다.
그 대신 AddListener, RemoveListener를 통해서 추가/삭제를 진행합니다.
public class MyButton : MonoBehaviour
{
public UnityEvent onClick;
void Start()
{
// 추가
onClick.AddListener(OnButtonClicked);
}
void OnDisable()
{
// 제거
onClick.RemoveListener(OnButtonClicked);
}
void OnButtonClicked()
{
Debug.Log("버튼이 클릭됨!");
}
}
두 이벤트는 하는 일은 동일하지만 여러 차이점이 있습니다.
| 항목 | UnityEvent | C# 이벤트 |
|---|---|---|
| 호출방식 | AddListener(), RemoveListener() | +=, -= |
| 인스펙터 연결 | 가능 | 불가능 |
| 직렬화 | Unity 에디터에 바로 저장 | 런타임에서만 보임 |
| 속도 | C# 이벤트보다 느림 | 상대적으로 빠름 |
Unity 에디터에 바로 저장되서 인스펙터에서 Drag & Drop으로 함수 연결하여
이벤트를 넣기 때문에 직관적이라 초보자가 이용하기에는 상당히 좋습니다.
Unity 에디터에서 이벤트를 조절하기 때문에 큰 프로젝트를 할 때
수정해야 할 경우에 디버깅이 상당히 힘들 수 있습니다.
즉, 직접 보면서 수정을 해야해서 시간이 많이 걸리는 단점이 있습니다.
그리고 속도는 UnityEvent가 좀 더 느리다고는 했지만 사실 체감상 차이가 없습니다.
그러면 둘 중에 뭘 써야 할까요?
사실 간단한 이벤트를 구현하는 것이라면 유니티 이벤트가 더 좋을 것이고,
체력 시스템, 상태 변화 같은 복잡한 게임 로직을 구현할 때는 이벤트에
정확한 추가/삭제가 필요한 경우에 C# 이벤트로 사용하는 것이 좋습니다.
그리고 보안성면에서도 외부에서 직접 호출 못하기 때문에
C# 이벤트로 사용하는 것이 좋습니다.
결국은 둘 다 괜찮으니 상황에 맞게 잘 선택해서 개발하는 것이 좋습니다.