UniRX 배우기 1) 스트림과 메시지

UniRX 깃허브 링크
https://github.com/neuecc/UniRx
데브루키_박민근_UniRX소개
https://www.slideshare.net/agebreak/160402-unirx

 

 

UniRx (Reactive Extensions for Unity)

 - .NET Reactive Extension을 유니티에 맞게 개량한 것.

 - LINQ 스타일 쿼리 연산자를 사용하여 비동기 및 이벤트 기반 프로그램을 작성하기 위한 라이브러리이다.

 - 유니티 에셋스토어에서 무료로 임포트가 가능하다.

 

UniRx - Reactive Extensions for Unity | 기능 통합 | Unity Asset Store

Use the UniRx - Reactive Extensions for Unity from neuecc on your next project. Find this integration tool & more on the Unity Asset Store.

assetstore.unity.com

 

Why Rx?

 - 일반적으로 Unity의 네트워크 작업에는 WWW 및 Coroutine을 사용할 수 있다.

 - 하지만 코루틴은 다음의 이유로 한계가 있다.

1. 코루틴은 반환 유형이 IEnumerator기 때문에 값을 반환할 수 없다.
2. yield return 문을 try-catch로 둘러쌀 수 없기 때문에 코루틴은 예외 처리할 수 없다.

 - UnityEvent를 구독할 수 있도록 확장 메서드가 준비되어있다.

 - 코루틴에도 대응되도록 구현되어있어 IEnumerator 내에서 UniRX의 콜백을 대기할 수도 있다.

 

 

UniRX를 사용하기 좋은 예

 - 아래와 같은 상황에서 사용하기 좋다고 한다.

 - 예시들의 용도가 event delegate와 유사한 것을 볼 수 있는데, UniRX는 event의 상위 호환이다.

1. 마우스 동작에 따라서 무언가 처리해야 할 때
2. 통신 응답 후 무언가 처리해할 때
3. 특정 값의 변화가 감지되면 무언가 처리해야 할 때

 

 

UniRX의 3단계

 - UniRX를 사용하려면 3가지 단계를 거치게 된다.

 - 연속적인 델리게이트 이벤트를 LINQ조건식으로 필터링 후 호출하는 느낌. 

1. 스트림(Stream)을 생성한다.
2. 스트림을 오퍼레이터를 사용하여 가공한다.
3. 가공된 스트림을 구독하여 사용한다.

 

 

스트림

 - 연속적인 이벤트(메시지)의 흐름.

 - 분기되거나 병합이 가능하다.

 - IObservable<T>로 구독이 가능하다.

 

 

메시지

 스트림에서 발행되는 메시지는 다음의 3종류가 존재한다. 

OnNext
 - 일반적으로 사용되는 메시지
OnError
 - 에러 발생 시 예외를 통지하는 메시지.
 - 구독자에게 도달한 순간 구독이 종료된다.
OnCompleted
 - 스트림 완료를 통지하는 메시지. 해당 메시지를 받으면 스트림이 종료된다.
 - 정적 스트림의 경우 OnCompleted를 받을 때까지 

 

 

IObserver, IObservable

 메시지 발행을 위한 IObserver 인터페이스와 메시지 구독을 위한 IObservable 인터페이스가 제공된다. 

IObserver : OnNext()OnCompleted()OnError() 
IObservable :Subscribe()

 

 

event를 대체하는 Subject

 - UniRX에서 제공하는 Subject<T>를 통해 UniRX의 스트림을 생성할 수 있다.

 - ISubject는 IObservable 과 IObserver를 구현하고 있다.

public interface ISubject<T> : ISubject<T, T>, IObserver<T>, IObservable<T>

 - subject 객체에서 OnNext(), OnCompleted(), OnError() 메시지를 직접 호출할 수 있다.

 

이벤트 게시자 스크립트

public class TestScript : MonoBehaviour
{
    public Subject<int> mySubject = new Subject<int>();

    IEnumerator Start()
    {
        var wait = new WaitForSeconds(1f);

        yield return wait;
        mySubject.OnNext(1);
        yield return wait;
        mySubject.OnNext(10);
        yield return wait;
        mySubject.OnCompleted();
    }
}

이벤트 구독자 스크립트

public class TestDisplay : MonoBehaviour
{
    void Start()
    {
        var mySubject = GetComponent<TestScript>().mySubject;
        mySubject.Subscribe(n => SomeMethod(n));
    }

    private void SomeMethod(int n)
    {
        Debug.Log(n);
    }
}

위의 예시에서 한 단계 더 나아가면 구독만 가능하도록 IObservable형식만을 노출할 수도 있다.

public IObservable<int> Observable => mySubject;
private Subject<int> mySubject = new Subject<int>(); // Subject는 숨긴다

 

 

 

 

댓글

Designed by JB FACTORY