LoginSignup
3
2

More than 5 years have passed since last update.

ボタンのロングタップ対応UniRx版 v0.3 [パフォーマンスに難有り]

Last updated at Posted at 2015-05-19

できること。
短いタップだったらShortTapを呼ぶ
IntervalAction秒長押しするとLongTapが呼ばれる。

ちょっとまだスマートじゃないのとこれだとチョンッってタップしただけでShortTapが呼ばれちゃうのでそこも何とかしたい。
あと長押ししていても指やカーソルが動きながらPressしてたらLongTapもShortTapも呼ばないようにしたい。
むずいぞ!

using UnityEngine;
using System.Collections;
using System;
using UniRx;
using System.Collections.Generic;


[RequireComponent(typeof(UIButton))]
public class UIButtonLongTapComponent : ObservableMonoBehaviour
{

    [SerializeField]
    float intervalAction = 3.0f;
    public UIScrollView scroll = null;
    float firstTapTime = 0f;
    bool isHoldAction = true;
    // 押しっぱなし時に呼び出すAction
    public Action OnLongTap = null;
    public Action OnShortTap = null;

    Vector3 tapPosition = Vector3.zero;

    BoolReactiveProperty isPressing = new BoolReactiveProperty();
    bool IsPressing { get { return isPressing.Value; } set { isPressing.Value = value; } }

    void Start()
    {
        scroll = this.transform.GetComponentInParents<UIScrollView> ();
        IsPressing = false;

        var tapInStream = this.UpdateAsObservable().Select(_=>IsPressing).Where (_ => _);
        var tapOutStream = this.UpdateAsObservable().Select(_=>IsPressing).Where (_ => !_);
        var tapInOutStream = this.UpdateAsObservable ().SkipUntil (tapInStream).TakeUntil (tapOutStream).Repeat ();

        var moveStream = tapInOutStream
            .Select(x=>scroll.currentMomentum.magnitude)
                .Scan((sum,current)=>sum+current)
                // .Do(x=>Debug.Log("currentMomentum: "+x))
                .FirstOrDefault(x=>x>0.1f)
                .Select(_=> "Move");

        var longTapStream = 
            tapInOutStream.TakeUntil(moveStream).SelectMany(_ => Observable.Timer(TimeSpan.FromSeconds(intervalAction))).Select(_ => "LongTap");


        longTapStream.Subscribe (_ => IsPressing = false);
        moveStream.Subscribe (_ => IsPressing = false);

        tapInStream.TakeUntil(moveStream).Timestamp()
            .SelectMany(_ => tapOutStream.Timestamp(), (s, e) => (e.Timestamp - s.Timestamp).Seconds >= intervalAction)
                .Select(x => x ? "LongTap" : "ShortTap")
                .Merge(longTapStream)
                .FirstOrDefault()
                .RepeatUntilDestroy(gameObject)
                .Subscribe(x =>{
                    Debug.Log(x);
                    if (x == "LongTap")
                        LongTap();
                    if (x == "ShortTap")
                        ShortTap();
                });

    }

    void OnPress (bool pressed)
    {
        IsPressing = pressed;
    }

    public void SetButtonAction(Action shortTap, Action longTap, bool isHoldLongTap) {
        isHoldAction = isHoldLongTap;
        OnLongTap = longTap;
        OnShortTap = shortTap;
    }

    public void CleanAction()
    {
        OnLongTap = null;
    }

    public void LongTap()
    {
        Debug.Log ("LongTap!!");
        if (OnLongTap != null)
            OnLongTap ();
    }
    public void ShortTap()
    {
        Debug.Log ("ShortTap!!");
        if (OnShortTap != null)
            OnShortTap ();
    }

}
3
2
2

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
3
2