유니티 이벤트(Unity Event)

allyosha_99
allyosha_99
∙∙조회 4

유니티 이벤트는 발행-구독 (Publish-Subscribe) 모델을 따르는 옵저버 패턴을 유니티 엔진에 맞게 구현한 것임.

여기서 ++옵저버 패턴++이란,

디자인 패턴 중 하나임.
옵저버 패턴은 일대다 의존성을 정의해주며, 이벤트를 발생시키는 발행자와 구독자로 역할을 완벽하게 분리해줌.
이는 C#의 객체지향 패턴과 완벽하게 맞물림.

 

유니티 이벤트의 또 다른 이점으로는 직렬화(Serialization)에 있음.

일반적인 C#의 델리게이트나 이벤트는 직렬화가 불가능하지만, 유니티 이벤트는 가능함!

unity

// 발행자 
public class Trap : MonoBehaviour
{
    public UnityEvent onTrapStepped;
    
    void OntriggerEnter(Collider other)
    {
        onTrapStepped?.Invoke();
    }
}

// 구독자
public class SoundManager : MonoBehaviour
{
    public Trap targetTrap; // => 인스펙터에서 Trap 오브젝트 연결
   
    void Start()
    {
        targetTrap.onTrapStepped.Addlistener(PlayExplosionSound);
    }

    void PlayExplosionSound() // Trap이 Invoke()를 호출하면 이 함수가 실행됨 !
    { 
        Debug.Log("쾅!");
    }
}

이런 식으로 객체간의 캡슐화를 보장하며 보다 직관적으로 구조를 파악하고 사용하는 게 가능토록 함.
이는 다시 말하면 두 객체, 호출자(Invoker)와 수신자(Listener)의 강한 결합을 끊어내어 독립성을 높인다고 할 수 있음.

 

사용법이 어렵진 않으니.. 간단하게 주요 API들만 몇가지 정리해봄.

Invoke()
  • 이벤트에 등록된 모든 메서드들을 일제히 순차적으로 실행함
unity
public UnityEvent onBossDied;

public void Die()
{
    // onBossDied 이벤트를 쏴서 연결된 리스너들을 모두 깨움
    onBossDied?.Invoke();
}

 

AddListener(UnityAction call)
  • 런타임에 이벤트를 추가(구독)함.
unity
void Start()
{
    // 게임 시작 시, 보스 사망 이벤트에 UI 출력 함수 ShowVictoryUI() 묶음.
    boss.onBossDied.AddListener(ShowVictoryUI);
}

void ShowVictoryUI() 
{
    Debug.Log("승리!");
}

 

RemoveListener(UnityAction call)
  • 런타임에 코드로 등록된 이벤트를 해제(구독 취소)함.
unity
void OnDestroy()
{
    // UI 매니저가 파괴될 때 구독 해제
    boss.onBossDied.RemoveListener(ShowVictoryUI);
}

 

RemoveAllListener()
  • 이벤트에 런타임(코드)로 등록된 모든 메서드를 한 번에 지움. (단, 인스펙터에서 수동으로 연결한 영구 리스너는 안됨)
unity
public void ResetLevel()
{
    // 스테이지 재시작 시 동적으로 연결된 모든 로직 초기화
    onBossDied.RemoveAllListeners();
}