[Unity] UniRX - 5 Operator
오퍼레이터(Operator)?
UniRx에서 Observable을 통해 관찰 대상이 결정되면 스트림에 값들을 흘려보내게 된다.
이 값들은 상황과 필요에 따라 기본값이 아닌 조작이나 필터링 등을 거쳐서 실제 내가 필요한 값들로 바꿔야 구독자에서 바로 사용할 수 있는 경우가 대부분일 것이다.
이 일련의 상황을 간단하게 그림으로 표현해 보면 아래와 같다.
이런 상황에서 데이터를 조작하게 해주는 명령어를 Operator라고 한다.
UniRx에서는 수십 가지에 달하는 정말 다양한 오퍼레이터를 제공한다.
그중에서도 상황에 맞는 오퍼레이터를 얼마나 잘 선택하느냐가 UniRx 활용 능력의 핵심이기도 하다.
이 포스팅에선 대표적인 오퍼레이터인 Where와 Select의 사용법을 살펴본다.
LINQ 에도 동일한 오퍼레이터가 있기 때문에 LINQ를 사용해 본 사람은 매우 익숙할 것이다.
Where
- IObservable에서 흐르는 이벤트 들 중에 필요 없는 이벤트를 걸러낼 수 있는 필터링 오퍼레이터
- Subscribe 안에서 최종적으로 넘겨받은 데이터들을 if 구문으로 체크한 후 사용할 수도 있겠지만 Where 오퍼레이터를 사용하면 훨씬 간결하면서 가독성 높은 코드를 만들 수 있다.
// 마우스 클릭 하고 있으면 ClickMouse 를 출력
Observable.EveryUpdate()
.Where(_ => Input.GetMouseButtonDown(0))
.Subscribe(_ => Debug.Log("ClickMouse"));
마우스 클릭 상태 체크
Update 되는 매 프레임을 스트림으로 흘려보내는데 Subscribe로 전달하기 전에 Where 오퍼레이터로 체크를 하면 true 인 경우에만 전달하고 false는 걸러내 주므로 Subscribe 내에서는 오직 데이터의 처리에만 집중할 수 있다.
Select
- 스트림을 변경하기 위해 사용하는 오퍼레이터
- int 타입의 데이터를 흘려보내는 스트림에서 Select 구문을 사용하면 다음부터는 다른 타입(예를 들어 Vector3 나 string 같은..)의 데이터를 전달하게 된다.
// 마우스 클릭 하고 있으면 현재 마우스 좌표를 출력
Observable.EveryUpdate()
.Where(_ => Input.GetMouseButtonDown(0))
// 이 스트림은 Select 이후로는 Vector3 타입의 mousePosition 을 통지한다.
.Select(_ => Input.mousePosition)
// Subscribe 에 통지되는 메세지는 Vector3
.Subscribe(x => Debug.Log(x));
위 Where 설명을 위한 샘플 코드에 Select 구문이 추가된 코드
Input.GetMouseButtonDown(0)가 true 일 경우에만 다음 오퍼레이터인 Select로 전달하므로 여기에서는 마우스 버튼을 클릭하고 있음을 보장받았기 때문에 스트림에 Vector3 타입인 Input.mousePosition 값을 흘려보낸다.
그러면 Subscribe에서는 마우스 버튼을 누르고 있을 때만 이 Vector3 좌표를 넘겨받으므로 최종 처리만 하면 된다.
SelectMany
- Select 가 기존 스트림에서 값을 바꾸는 처리를 수행하는데 비해 SelectMany는 새로운 스트림을 생성하여 본래의 스트림을 대체시킨다.
public Button button;
void Start()
{
button.OnPointerDownAsObservable() //button 에 Pointer Down 이벤트 발생 Observable
// 매 프레임 관찰하는 스트림을 새로 생성하여 대체
.SelectMany(_ => button.UpdateAsObservable())
// 매 프레임 관찰하는 스트림 중에 button 의 Pointer Up 이 오면 중단
.TakeUntil(button.OnPointerUpAsObservable())
.Subscribe(_ =>
{
Debug.Log("pressing...");
});
}