유니티이벤트(UnityEvent)와 액션 델리게이트(Action Delegate)의 차이
UnityEvent는 Unity의 이벤트 시스템의 일부로, UnityEngine.Events 네임스페이스에 속합니다.
이는 Action 과 비슷한 개념이지만, Unity의 시리얼라이징(Serializing) 기능과 통합되어 있어 인스펙터(Inspector)에서 직접 이벤트를 관리하고, 리스너(listener)를 할당할 수 있게 해줍니다. 이로 인해, 게임 개발 시 비개발자도 쉽게 이벤트를 설정하고 조작할 수 있습니다.
UnityEvent와 Action의 주요 차이점은 다음과 같습니다.
- 시리얼라이징: UnityEvent는 Unity인스펙터에서 시각적으로 수정할 수 있도록 설계되어 있으며, 게임 오브젝트와 컴포넌트에 연결된 이벤트를 쉽게 설정할 수 있습니다. 반면, Action은 코드내에서만 사용되며, 인스펙터를 통한 직접적인 시각적 조작은 지원하지 않습니다.
- 성능: 일반적으로 Action이 UnityEvent보다 성능이 더 높습니다. UnityEvent의 유연성과 인스펙터 통합 기능은 추가적인 오버헤드를 발생시키기 때문에, 성능이 중요한 상황에서는 Action이나 기타 델리게이트를 사용하는 것이 더 효율적일 수 있습니다.
- 사용 용도: UnityEvent는 주로 인스펙터에서 이벤트를 관리하고, 디자이너나 비개발자가 작업을 용이하게 할 필요가 있을 때 사용됩니다. Action은 코드 내에서 더 많은 제어가 필요하거나 성능이 중요한 경우 사용됩니다.
- 추가 설명: Action은 C#의 델리게이트 타입 중 하나입니다. 델리게이트는 메서드에 대한 참조를 안전하게 저장할 수 있는 타입이며, 이를 통해 메서드를 변수처럼 전달하고 실행할 수 있습니다. Action은 반환 값이 없는 메서드를 참조하기 위한 델리게이트이며, 여러 개의 매개변수를 받을 수 있는 여러 오버로드가 있습니다. 주 용도는 이벤트 처리, 콜백 함수 설정, 또는 어떤 메서드를 다른 메서드에 인자로 전달할 필요가 있을 때 사용됩니다. UnityEvent는 Unity엔진의 UnityEngine.Events 네임스페이스에 정의된 클래스입니다. 이 클래스는 Unity의 이벤트 시스템을 위해 설계되었으며, 시리얼라이즈가 가능하므로 Unity인스펙터에서 직접 수정할 수 있습니다. 주요 기능으로는 이벤트를 발생시키고, 해당 이벤트에 대한 리스너(listener)들을 관리하는 기능을 제공합니다. 인스펙터를 통해 시각적으로 리스너를 추가하고, 이벤트오 ㅏ연결된 메서드를 지정할 수 있습니다. UnityEvent는 매개변수를 받는 이벤트를 정의하기 위해 제네릭 버전도 제공합니다. (UnityEvent<T>, UnityEvent<T0, T1> 등)
따라서, Action은 델리게이트(즉, 메서드 참조 타입)로, UnityEvent는 이벤트 관리를 위한 클래스로 간주할 수 있습니다. 두 개념 모두 메서드를 다루지만, 사용 방식과 목적이 다릅니다.
UnityEvent가 시리얼라이즈 가능한 클래스인 이유는 주로 인스펙터에서의 사용 편의성과 Unity의 컴포넌트 시스템과의 통합을 위해서입니다. Unity에서 시리얼라이즈(Serialize)기능이 있다는 것은 해당 객체를 Unity 에디터가 읽고 쓸 수 있다는 의미이며, 이는 여러 가지 중요한 용도로 활용됩니다.
- 인스펙터 노출: 가장 직관적인 용도는, 개발자나 게임 디자이너가 Unity의 인스펙터 창을 통해 쉽게 객체의 상태를 수정할 수 있게 하는 것입니다. 이는 코드 변경 없이도 이벤트 리스너를 추가하거나 수정할 수 있게 하여 개발 프로세스를 단순화시킵니다.
- 프리팹(Prefab)및 씬(Scene)설정 저장: 시리얼라이즈된 UnityEvent는 프리팹이나 씬 파일에 그 상태가 저장되므로, 게임을 실행할 때 같은 설정을 재현할 수 있습니다. 이는 게임의 다양한 상호작용을 설정하는데 매우 중요합니다.
- 게임 빌드 시 정보 유지: Unity게임을 빌드할 때, 시리얼라이즈된 정보는 게임 데이터의 일부로 포함됩니다. 이는 게임 실행 시 UnityEvent에 설정된 리스너와 이벤트가 정상적으로 작동하도록 보장합니다.
즉, UnityEvent의 시리얼라이즈 기능은 서버와의 데이터 교환 목적보다는 개발 과정에서의 편의성, 게임 설정의 유지 및 관리 측면에서 중요한 역할을 합니다. Unity의 이벤트 시스템은 개발자가 인스펙터를 통해 시각적으로 게임 로직을 구성할 수 있게 하여, 코드를 수정하지 않고도 다양한 게임 내 상호작용을 쉽게 설정하고 실험할 수 있는 유연성을 제공합니다.
또 다른 차이점
C#에서 event 한정자는 클래스 또는 구조체 내부에 사용되며, 해당 델리게이트 형식의 이벤트를 선언할 때 사용됩니다. event 한정자는 해당 이벤트에 대한 구독(+= 연산자를 통한 리스너 추가)과 구독 취소(-=연산자를 통한 리스너 제거)는 허용하지만, 이벤트를 직접 호출(예: myEvent.Invoke()) 하는 것은 선언한 클래스나 구조체 내에서만 가능하도록 제한합니다. 이는 이벤트의 캡슐화를 강화하고 외부에서의 무분별한 호출을 방지합니다.
UnityEvent는 Unity의 시스템에 특화된 클래스입니다. UnityEvent는 인스펙터에서 시각적으로 이벤트를 관리할 수 있도록 설계되었으며, 리스너를 동적으로 추가하거나 제거하는 기능 외에도, 직접 호출(Invoke())할 수 있는 기능을 제공합니다.
UnityEvent는 event 키워드로 선언되지 않습니다. 왜냐하면 UnityEvent 자체가 이미 이벤트 관리 및 호출을 위한 캡슐화된 메커니즘을 내장하고 있기 때문입니다. 따라서 UnityEvent의 인스턴스는 외부에서 리스너를 추가하거나 제거할 수 있을 뿐만 아니라, Invoke() 메서드를 사용하여 외부에서 호출할 수 있습니다. 이는 event 한정자와 함께 사용되는 일반적인 C#델리게이트와는 다른 점입니다.
C#에서 event 한정자는 주로 델리게이트(Delegate) 타입의 멤버에 사용되어, 해당 멤버를 이벤트로 선언합니다. 이는 클래스 또는 구조체(struct) 내에서 이벤트를 정의할 때 사용되며, 이벤트의 구독 및 구독 취소는 허용하지만, 이벤트의 직접 호출은 해당 클래스나 구조체 내부에서만 가능하게 제한하는 캡슐화 메커니즘을 제공합니다.
event 한정사는 델리게이트 타입에만 사용할 수 있습니다. 즉, 메서드 참조를 위한 타입인 Action, Func<>, 또는 사용자 정의 델리게이트 타입에 사용될 수 있습니다. 이외의 다른 타입(예: 변수, 메서드 등)에는 event 한정자를 사용할 수 없습니다.