ScrollRect 内でタップと長押しで処理を分けたい、みたいなの結構あると思うんですが、
パッと探しても見つからなかったので書きました。
ScrollablePointerTrigger
using UnityEngine;
using System;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using UniRx;
using UniRx.Triggers;
[RequireComponent(typeof(ObservablePointerUpTrigger))]
[RequireComponent(typeof(ObservablePointerDownTrigger))]
[RequireComponent(typeof(ObservablePointerClickTrigger))]
public class ScrollablePointerTrigger : MonoBehaviour
{
[NonSerialized] public float pressTime = .5f;
public IObservable<PointerEventData> OnPointerDownAsObservable => GetComponent<ObservablePointerDownTrigger>().OnPointerDownAsObservable();
public IObservable<PointerEventData> OnPointerUpAsObservable => GetComponent<ObservablePointerUpTrigger>().OnPointerUpAsObservable();
public IObservable<PointerEventData> OnPointerClickAsObservable => GetComponent<ObservablePointerClickTrigger>().OnPointerClickAsObservable();
Subject<Unit> onLongPressedSubject = new Subject<Unit>();
IObservable<Unit> _onLongPressedObservable;
public IObservable<Unit> OnLongPressedObservable
{
get
{
if (_onLongPressedObservable == null)
{
_onLongPressedObservable = onLongPressedSubject;
OnPointerDownAsObservable
.SelectMany(_ => Observable.Timer(TimeSpan.FromSeconds(pressTime)))
.TakeUntil(OnPointerUpAsObservable)
.RepeatUntilDestroy(this.gameObject)
.Subscribe(_ => onLongPressedSubject.OnNext(Unit.Default));
}
return _onLongPressedObservable;
}
}
Subject<Unit> onShortPressedSubject = new Subject<Unit>();
IObservable<Unit> _onShortPressedObservable;
public IObservable<Unit> OnShortPressedObservable
{
get
{
if (_onShortPressedObservable == null)
{
ScrollRect scrollRect = GetComponentInParent<ScrollRect>();
IObservable<PointerEventData> OnDragAsObservable;
if (scrollRect == null)
{
OnDragAsObservable = gameObject.AddComponent<ObservableDragTrigger>().OnDragAsObservable();
}
else
{
OnDragAsObservable = scrollRect.OnDragAsObservable();
}
_onShortPressedObservable = onShortPressedSubject;
OnPointerDownAsObservable.Timestamp()
.Zip(OnPointerClickAsObservable.Timestamp(), (d, u) => (u.Timestamp - d.Timestamp).TotalMilliseconds / 1000.0f)
.Where(time => time < pressTime)
.TakeUntil(OnDragAsObservable)
.TakeUntil(OnLongPressedObservable)
.RepeatUntilDestroy(this.gameObject)
.Subscribe(t => onShortPressedSubject.OnNext(Unit.Default));
}
return _onShortPressedObservable;
}
}
Subject<Unit> onStayPressedSubject = new Subject<Unit>();
IObservable<Unit> _onStayPressedObservable;
public IObservable<Unit> OnStayPressedObservable
{
get
{
if (_onStayPressedObservable == null)
{
_onStayPressedObservable = onStayPressedSubject;
OnPointerDownAsObservable
.SelectMany(_ => this.UpdateAsObservable())
.TakeUntil(OnPointerUpAsObservable)
.RepeatUntilDestroy(this)
.Subscribe(_ => onStayPressedSubject.OnNext(Unit.Default));
}
return _onStayPressedObservable;
}
}
}