오르카의 아틀리에

 

이벤트를 처리하다 보면 A가 일어난 후에 B가 일어나기까지 반복작업해야 하는 일을 만들어야 할 때가 있다. 예를 들어 (예제의 내용이지만) 마우스 드래그를 표현할 때 마우스 버튼이 눌리고 때어질 때까지 마우스의 움직임을 캡처하여 오브젝트의 회전에 반영하는 상황이나 특정 조합키를 입력해서 캐릭터의 춤동작 애니메이션을 재생하고 다른 특별한 입력이 있을 때까지 애니메이션을 반복 재생하는 상황이 있을 수 있겠다.

 

우선 기존의 프로그래밍 방법을 유니티 초심자의 입장에서 생각해보자. 마우스 드래그를 보게 되면 (1)오브젝트의 Update 문에 마우스의 위치와 오브젝트의 Rotation을 연동시키는 코드를 삽입하고 또, (2)마우스 버튼이 눌렸을 때와 릴리즈될 때를 캐치하여 bool 변수(isDraged 정도)를 통해 그 연동 구문을 활성화/비활성화할 수 있게 해두는 정도를 생각할 수 있을 것이다. 

 

 

 

 

 

어때 보이는가? 상당히 귀찮아 보인다. 또한 어떤 조건에서 드래그 구문을 실행하는지도 '마우스와 오브젝트 Rotation을 연동하는 로직'만 보고는 알기 힘들다. (실행을 결정하는 부분이 외부에 메소드 형태로 있으니...) 이런 요소들이 한 구문에 있다면 이 로직이 어떤 로직이고 어떠어떠한 조건에서 실행되는지 한눈에 파악할 수 있을 것이다. UniRx는 그걸 가능하게 한다. UniRx는 어떻게 이런 로직들을 보기 좋게 처리할 수 있을까?

 

SkipUntil

인자를 통해 지정한 스트림에 메시지가 올때 까지 해당 스트림의 메시지를 스킵한다.

기본적으로 특정 이벤트가 발생하기 전까지 메시지를 스킵하는 오퍼레이터다. 계속 마우스 드래그 예제를 이용하면, 마우스 버튼이 눌릴 때까지 EveryUpdate 스트림에 들어오는 모든 메시지를 무시할 수 있는 것이다. 

 

TakeUntil

인자를 통해 지정한 스트림에 메시지가오면 OnCompleted를 통해 스트림을 종료한다.

이 오퍼레이터는 스트림을 어디까지 실행할 것인지를 결정한다. 이 오퍼레이터를 사용하면 마우스 버튼이 릴리즈되기 전까지만 스트림에서 메시지를 받을 수 있다. 즉, 위에 설명한 SkipUntil과 함께 사용하면 마우스 버튼이 눌릴때 부터 릴리즈되기 전까지만 Update 스트림의 메시지를 받을 수 있는 것이다.

 

하지만 문제가 있다. 이렇게 사용하게 되면 TakeUntil을 통해 구독한 스트림에 OnCompleted가 들어오기 때문에 스트림이 종료된다. 즉, 프로그램 실행 시간에서 단 한 번만 드래그할게 아니면 다른 추가적인 조치를 취해야한다.

 

Repeat

스트림이 OnCompleted를 통해 종료될때 다시한번 Subscribe한다

이 오퍼레이터를 통해 TakeUntil이 스트림을 종료시키면 다시한번 초기 상태로 Subscribe하게 만들 수 있다. 이 3가지 오퍼레이터를 조합하면

 

1. SkipUntil : 버튼이 눌릴 때까지 아무 것도 하지 않다가

2. Subscribe : 버튼이 눌린 후에 로직을 처리하고

3. TakeUntil : 처리 중에 버튼이 때지면 로직을 멈추고 스트림을 종료

4. Repeat : 종료 후 다시 재구독

 

이런 작업이 가능하다는 것이다. 샘플 코드를 보고 어떻게 사용했는지 자세히 보자.

 

 

이런 식으로 처리하면된다. 이것은 마우스 드래그의 예제 였지만, 확장시켜 A 이벤트와 B이벤트 사이의 일을 한 구문으로 처리할 수 있게된다. 자세한 예제 모음집은 이곳을 통해 확인할 수 있다.