Update()를 Observable로 변환하여 사용하는 경우
Update를 Observable로 변환하는 방법은 아래 세 가지 방법이 있습니다.(2015 / 04 / 10 시점 기준)
- Observable.EveryUpdate
- ObservableMonoBehaviour & UpdateAsObservable
- ObservableUpdateTrigger & UpdateAsObservable
각 방법마다 차이가 있기 때문에 주의를 해야 합니다.
Observable.EveryUpdate
Observable.EveryUpdate는 static으로 정의되어 있기 때문에 MonoBehaviour 외부에서 호출하여 사용할 수 있습니다. 그리고 내부적으로는 MainThreadDispatcher의 코루틴의 실행 타이밍에서 돌게 됩니다.
주의해야 할 점은 Dispose 호출을 명시적으로 직접 처리해 주어야 합니다.
Observable
. EveryUpdate ()
. Subscribe ( x => Debug . Log ( x ));
- static 으로 정의되어 있기 때문에 MonoBehaviour 이외의 장소에서도 사용할 수 있다.
- 실체는 MainThreadDispatcher 라는 게임 오브젝트에서 돌게 되는 코루틴 내에서 실행. 그렇기 때문에 엄밀히 말하면 Update()의 타이밍이 아니라 코루틴의 실행 타이밍 에서 돌게 된다.
- 스트림은 프레임 수(Time.countFrame)가 흘러 나온다. (위의 코드에서 x가 프레임 수)
- Subscribe의 Dispose 호출을 명시적으로 직접 호출해야 한다. (혹은 AddTo 를 사용하여 GameObject가 Destory할 때 Dispose 함수가 호출하도록 처리해야 한다)
ObservableMonoBehaviour
UpdateAsObservable는 내부적으로 Subject를 가지고 있으며, Update시 OnNext를 호출하는 그냥 단순한 구조로 되어 있습니다. (코드 확인하기) 따라서 Update를 Override할 때 base.Update()의 호출을 제대로 추가해주지 않으면 UpdateAsObservable()이 작동하지 않기 때문에 주의를 할 필요가 있습니다.
UniRx 4.8 이후 버전에서는 ObservableMonoBehaviour 를 지원하지 않으므로 주의합니다. 대신 ObservableUpdateTrigger를 사용하는 것을 권장합니다.
public class UniRxSample : ObservableMonoBehaviour
{
public override void Start ()
{
base . Start ();
UpdateAsObservable ()
. Subscribe ( _ => Debug . Log ( "Update!" ));
}
public override void Update ()
{
// Update를 override 할 때는 base.Update () 호출을 잊지 않는다.
base . Update ();
}
}
- ObservableMonoBehaviour는 MonoBehaviour의 파생 클래스이며 이것을 상속하여 사용할 필요가 있다.
- UpdateAsObservable()은 Update 타이밍에 돌게 된다.
- Component가 파괴되면 Dispose된다.
- 스트림은 IObservable\
- ObservableMonoBehaviour에는 Update 이외에도(FixedUpdate, LateUpdate 등) 준비되어 있기 때문에 상황에 맞게 사용할 수 있어서 편리하다.
- Script Execution Order에서 다른 스크립트들과 실행 순서를 정할 수 있다.
ObservableUpdateTrigger
ObservableUpdateTrigger는 MonoBehaviour의 Update 함수의 호출마다 OnNext 메시지를 통지, 처리합니다.
using UniRx.Triggers ;
public class UniRxSample : MonoBehaviour
{
private void Start ()
{
this . UpdateAsObservable ()
. Subscribe ( _ => Debug . Log ( "Update!" ));
}
}
- ObservableUpdateTrigger는 UniRx.Triggers라는 네임스페이스에 정의되어 있다.
- UnIRx.Triggers를 Using하지 않으면 UpdateAsObservable를 직접 호출하는 것은 불가능.
- 호출한 다음 자동으로 Trigger가 AddComponent 된다. (실제로 사용할 때는 Trigger의 존재는 신경쓰지 않아도 된다.)
- ObservableMonoBehaviour와 내부 구조는 동일하다.
정리
MonoBehaviour의 Update를 스트림 소스로 Observable을 생성할 때 일반적인 방법은 UpdateAsObservable()를 사용하는 것이 가장 간단하고 사용하기 쉬운 방법입니다. MonoBehaviour 외의 다른 곳에서 Update 마다 메시지의 통지가 필요한 경우와 같이 처리에 따라서는 Observable.EveryUpdate을 사용합니다.