よくありそうなんですが、これぞというものが無かったのでまとめてみます。
##発行側
クリックの定義(例としてここではマウスダウン)
var clickStream =
Observable
.EveryUpdate()
.Where(_ => Input.GetMouseButtonDown(0));
ダブルクリック時に発行(要Connect)
var doubleClickInterval = 250d;
DoubleClickStream =
clickStream
.TimeInterval()
.Select(t => t.Interval.TotalMilliseconds)
.Buffer(2, 1)
.Where(list => list[0] > doubleClickInterval)
.Where(list => list[1] <= doubleClickInterval)
.Publish();
##購読側
DoubleClickStream
.Subscribe(_ => { hoge; });
#参考にさせてもらったもの
##時間でまとめる
http://www.slideshare.net/torisoup/unity-unirx/79
.Buffer(clickStream.Throttle(TimeSpan.FromMilliseconds(200)))
.Where(x => x.Count >= 2)
最後のクリックから指定時間経過すると発火し、その間の回数が2回以上かどうかで判定するやり方。
シンプルなんですが、実際試してみるとダブルクリックした瞬間ではなく最後に一定時間待たないといけないため、UIとしては反応が悪く感じられます。2回以上連続でクリックし続けたケースでも最後のクリックが終わるまで発火しません。
##カウントでまとめる
http://naichilab.blogspot.jp/2014/07/unityunirx.html
最初に書いたものとだいたい同じですが
.Buffer(2)
でまとめるとストリームを2個ずつ取り出す形になり、[0,1], [2,3], [4,5]...と偶数クリック目にしか発火しません。
.Buffer(2, 1)
skip値を指定すると、[0,1], [1,2], [2,3] と常に最新のペアが得られます。
#各部解説
var doubleClickInterval = 250d;
ダブルクリックと判定する間隔(ms)です。お好みで適当に設定しましょう。
.TimeInterval()
前回のクリックからの時間の差分を取得します。
.Buffer(2, 1)
最新2個のペアを取得します。
.Where(list => list[0] > doubleClickInterval)
.Where(list => list[1] <= doubleClickInterval)
ここでダブルクリックであるかどうかを以下の条件で判定します。
- 最新ひとつ前のクリックの前回との差分:指定時間より大きい
- 最新クリックの前回との差分: 指定時間以下
前者の判定が何故必要なのかというと、3回以上連続でクリックし続けた場合にダブルクリックが何度も発行されてしまうからです。
----c1-c2-c3-c4-c5----c6----c7----c8-c9----
たとえば上記のような間隔でクリックした場合、c2とc9でのみダブルクリックを発行します。
(c4もダブルクリックとする場合には対応してません)