LoginSignup
0
0

More than 3 years have passed since last update.

[ UniRx ] ScrollRect 内のタップ、長押し判定

Last updated at Posted at 2020-11-09

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;
        }
    }
}

参考:【UniRx】マウスの長押しを判定する

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0