読者です 読者をやめる 読者になる 読者になる

unity study

Unityでサクッとモックを作れるようになることを目指して、基本的なテクニックを抑えていく過程を残すブログのつもりだったけど、今はただ自分のトラブルシューティングメモになってるブログ

一度発火してから、一定時間以内に再発火しなかったら終了するストリーム

断続的に値が流れてくるストリームがあり、一定時間以内に値が来たら処理するが、一定時間以上値が流れて来なかったら終了する、という処理をしたいと思った。
例えばスコアを獲得する毎に値が流れてくるストリームがあるとして、これ自体は明確な終了がない。
しかし発火したタイミングで画面に表示を出したいが、表示するのは直近の1つだけにしたい。
更に表示から一定時間経過したら非表示にしたい。
というようなことをやる場合に、まぁ無理にストリームでやらなくても処理はできるのだが、スマートに書けないものか、と考えてみた。
で、こうなった。
例として、ボタン押下毎に発火するが、一定時間以上発火がなければ終了とするストリーム。

var tapStream = this.UpdateAsObservable().Where(_ => Input.GetMouseButtonDown(0));
tapStream
	.Select(_ => Time.frameCount)
	.TakeUntil(tapStream.Throttle(TimeSpan.FromSeconds(1)))
	.DoOnCompleted(() => Debug.Log("complete"))
	.RepeatUntilDestroy(this)
	.Subscribe(x => Debug.Log("frameCount: " + x)));

このThrottleさせたストリームを条件に使う、ってのがなかなかパッと思い浮かばなかったりするんだよなぁ。
Bufferの条件に使ったりとか、うまく使うと色々やりたいことをスマートに書けるので便利。

【追記】
上記の場合はUpdateAsObservableに対してRepeatするからいいけど、ソースがReactivePropertyだともうちょっとなんか考えないとダメっぽいな。