本日はUniRxの小ネタ枠です。
UniRxのContinueWithを使ってIObservableを一度だけ差し替える方法を記事にします。
前提条件
UniRxの環境構築手順は以下の記事を参照ください。
bluebirdofoz.hatenablog.com
UniRxのContinueWithを使ってIObservableを一度だけ差し替える
UniRxのContinueWithはObservableから新しいIObservableを返します。
また、この差し替えが行われるのはOnCompletedが呼び出されたタイミングの一回のみという特徴があります。
以下にサンプルスクリプトを作成しました。
こちらはIObservableの差し替えがシーン再生5秒後に一度のみ実行されます。
・UniRxContinueWithTest.cs
using System; using UniRx; using UnityEngine; public class UniRxContinueWithTest : MonoBehaviour { private void Start() { // 5秒後に一度のみ通知が行われる Observable.Timer(TimeSpan.FromSeconds(5.0f)) .Do(_ => Debug.Log($"通知が行われました")) // 一回だけObservableの差し替えが行われる .ContinueWith(_ => { var timerSec = 3.0f; return Observable.Interval(TimeSpan.FromSeconds(timerSec)).Select(count => (count+1)*timerSec); }) // 以降はIntervalの通知を基にログを出力する .Subscribe(elapsedTime => Debug.Log($"{elapsedTime}秒前に通知が行われました")); } }
ContinueWithによるObservableの差し替えはOnCompletedが呼び出されたタイミングで実行されます。
このため、以下のようにTimerを完了しないコードに変更するとContinueWithによる差し替えは動作せず、Observable.Intervalの通知が発生しません。
・UniRxContinueWithTest.cs
using System; using UniRx; using UnityEngine; public class UniRxContinueWithTest : MonoBehaviour { private void Start() { // 5秒後から定期的に通知が行われる Observable.Timer(TimeSpan.FromSeconds(5.0f), TimeSpan.FromSeconds(5.0f)) .Do(_ => Debug.Log($"通知が行われました")) // 本コードではObservableの差し替えが行われない .ContinueWith(_ => { var timerSec = 3.0f; return Observable.Interval(TimeSpan.FromSeconds(timerSec)).Select(count => (count+1)*timerSec); }) .Subscribe(elapsedTime => Debug.Log($"{elapsedTime}秒前に通知が行われました")); } }