반응형


 유니티에서 버튼에 CallBack을 등록시키기 위해서 에디터에서 클래스와 메쏘드를 지정하는 방법이 있고, 스크립트에서 직접 등록하는 방법이 있다.

이 때 등장하는 것이 UnityEvent이다. UnityEvent는 MonoBehavior를 상속받는 모든 클래스에 사용가능하다. 일단 선언이 되면 Editor에서 CallBack 함수를 등록하는 GUI가 추가되는 것을 볼 수 있다.


간단하기야 당연히 이렇게 Editor에서 Class의 Method를 지정해 주는 것이 간단하지만, 실제로는 에셋과 스크립트 간의 버젼 충돌을 피하고 원활한 업데이트를 위해서 스크립트로 이벤트를 집어 넣어주는 경우가 많다. 그 때 쓰이는 함수가 AddListener이다.

인자로 들어가는 것이 Events.UnityAction인데 이 UnityAction은 유니티에서 엔진에서 사용하려고 미리 만들어 놓은  C# Delegate이다. 정의는 아래와 같이 void부터 4개의 인자를 가지는 Delegate까지 커버한다. 


 그렇다면 해당 Delegate를 등록받는 onClick 이라는 녀석은 무엇일까?
바로 이 onClick이 UnityEventBase를 상속받는 UnityEvent 클래스의 Instance이다.  즉, 이 Class의 Instance에 UnityAction을 Register하는 것이다. 그런 다음 해당 클래스의 Invoke 메소드가 호출되면서 모든 등록된 Delegate들이 실행되게 된다.

 

UnityEvent가 UnityAction을 취하는 방법을 살펴 보면, 

위 코드에서 A키를 8회 눌렀을 때 출력은 아래와 같다. 순서대로 찍히고 마지막에 다 찍힌다.

 

동일한 기능을 하는 코드를  UnityEvent와 UnityAction을 이용하면 아래와 같이 구현할 수 있다. 

이렇게 하면 코드량은 조금 더 길어 보일 지 모르나, 각 이벤트에 등록된 UnityAction의 추가(AddListener) 및 삭제(RemoveListener)가 동적으로 자유로우므로, 마치 Observer Pattern을 적용한 느낌도 나면서 훨씬 더 유연한 코드 작성이 가능하다. (사실 UnityEvent는 미리 구현하여 내장된 Observer Pattern으로 보는 것이 맞을 것이다.)


아래와 같이 추상 클래스인 UnityEvent<T0>를 상속하여 선언함으로써 인자를 넘겨 주는 타입의 UnityAction을 호출할 수도 있다. 인자를 4개 받는 것까지 확장 가능하다.


Unity에서 사용하는 Mono 2.x는 C# 3.0까지는 안전하게 지원하므로, C# 3.0 버젼의 Lambda를 이용할 수 있다. Lambda expression은 anonymous function의 일종으로 이를 이용하면 간단히 delegate를 생성 가능하다.  따라서, 아래와 같이 동일 기능을 더 간단히 구현할 수 있다. Lambda 정의 Ref

또한, C# 2.0에서부터 도입된, delegate-method-group-conversion에 의해서 바로 Method name을 Delegate에 Assign할 수도 있다. 

이러한 모든 방법들을 다 Event를 거는데 활용해보면, 결과적으로 다음 코드와 같이 다양한 형태를 받는 AddListener가 나올 수 있게 된다.

 

출력은 아래와 같고 버튼 클릭 시에 모두 잘 동작한다. 

UnityEvent와 UnityAction에 대한 이러한 이해를 기반으로 Unity Official Tutorial 에 나와있는 EventManager Tutorial를 살펴보면 이해가 훨씬 쉽다.

 


ref : http://rapapa.net/?p=2936



반응형

+ Recent posts