Search code examples
c#unity-game-enginesystem.reactiveunirx

C# reactiveX multitouch drag clear buffer on OnPointerUp Event


I'm trying to implement multitouch drag in unirx for unity. I use the Buffer(count, skip) overload to get last to events for each finger and calculate the distance.

I now would like the clear the Buffer when a finger is lifted, otherwise the old value that is still in the buffer will create a large delta.

 private IObservable<TwoFingerDragEventData> CalculateDelta(IObservable<PointerEventData> dragEvent, int pointerId) {

    return dragEvent
      .Where(data => data.pointerId == pointerId)
      .Select(data => data.position)
      .Buffer(2, 1)
      .Select((IList<Vector2> list) => new TwoFingerDragEventData(
        Vector2.Distance(list[0], list[1]),
        list[1] - list[0]
      ))
    ;
  }

Solution

  • I solved it now by wrapping the whole thing into another observable.

    I use a BehaviourSubject<bool> isDragActiveSource which is set to true on drag start event and set to false on drag stop event.

    isDragActiveSource
      .AsObservable()
      .Where(isActive => isActive == true)
      .SelectMany((bool _) => {
        IObservable<TwoFingerDragEventData> firstTouch = CalculateDelta(onDrag, 0);
        IObservable<TwoFingerDragEventData> secondTouch = CalculateDelta(onDrag, 1);
    
        return firstTouch.Zip(
          secondTouch,
          (TwoFingerDragEventData left, TwoFingerDragEventData right) => TwoFingerDragEventData.Avg(left, right
        ).TakeUntil(isDragActive.Where(isActive => isActive == false));
      })
    

    When the BehaviourSubject emits false firstTouch and secondTouch Observables are completed (takeUntil) and when it becomes true again they are re-created.