探せば誰かが書いていそうですが、一つの参考として
拡張メソッド側のスクリプト
UIExtensions.cs
using System;
using UnityEngine.UI;
using UniRx;
using UniRx.Triggers;
public static class UIExtensions
{
public static IObservable<Unit> OnLongTapAsObservable(this Button button, float pressSeconds = 1f)
{
return button
.OnPointerDownAsObservable()
.Throttle(TimeSpan.FromSeconds(pressSeconds))
.TakeUntil(button.OnPointerExitAsObservable()) // 押したまま指がボタン領域から離れたら終了
.TakeUntil(button.OnPointerUpAsObservable())
.RepeatUntilDestroy(button)
.AsUnitObservable();
}
public static IObservable<Unit> OnClickAsObservableSafety(this Button button, float duplicateSafetySeconds = 1f, float pressSafetySeconds = 1f)
{
return button
.OnClickAsObservable()
.ThrottleFirst(TimeSpan.FromSeconds(duplicateSafetySeconds)) // 連打防止
.SkipUntil(button.OnPointerDownAsObservable())
.TakeUntil(button.OnLongTapAsObservable(pressSafetySeconds)) // 長押し後に指を離してもタップイベントを発行しない
.RepeatUntilDestroy(button)
.AsUnitObservable();
}
}
使用例
Hoge.cs
using UnityEngine;
using UnityEngine.UI;
using UniRx;
public class Hoge : MonoBehaviour
{
[SerializeField] Button button = null;
void Start()
{
button
.OnLongTapAsObservable()
.Subscribe(_ => Debug.Log("ボタンがロングタップされたよ!"));
button
.OnClickAsObservableSafety()
.Subscribe(_ => Debug.Log("ボタンがタップされたよ!"));
}
}
補足
ロングタップ後に指を離した際、タップイベントも発行されるという挙動が気に入らなかったので、
OnClickAsObservableSafety()も併せて用意する事でこれを解消しています。
なのでタップもロングタップも両方ボタンに設定したい場合は、
タップについてもこちらの拡張の方を使うことを想定しています。
※タップは反応しないけどロングタップは反応するボタン、はこの世に存在するのか…?