76 lines
2.4 KiB
C#
76 lines
2.4 KiB
C#
using System;
|
|
using UnityEngine;
|
|
using UnityEngine.EventSystems;
|
|
using UnityEngine.UI;
|
|
|
|
/// <summary>
|
|
/// Toggle 长按检测器:挂在 Toggle 同一个物体上。
|
|
/// - 短按:不干预,Toggle 自己正常翻转(走原有 onValueChanged 逻辑)
|
|
/// - 长按(按住超过 longPressTime):触发一次 onLongPress,并吞掉松手时的 Toggle 翻转
|
|
/// (松手瞬间 Toggle 的 OnPointerClick 因 interactable=false 不会翻转 isOn,下一帧恢复)
|
|
/// 用法:面板 Start 里 AddComponent 到目标 Toggle 上并订阅 onLongPress。
|
|
/// </summary>
|
|
public class ToggleLongPress : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
|
|
{
|
|
[Tooltip("长按判定时间(秒):按住超过此时间触发 onLongPress,提前松手不触发")]
|
|
public float longPressTime = 0.6f;
|
|
|
|
/// <summary>长按达到阈值时触发一次(提前松手不触发)</summary>
|
|
public event Action onLongPress;
|
|
|
|
private Toggle _toggle;
|
|
private bool _pressing;
|
|
private float _timer;
|
|
private bool _fired;
|
|
private bool _restoreInteractable;
|
|
|
|
private void Awake()
|
|
{
|
|
_toggle = GetComponent<Toggle>();
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (_pressing)
|
|
{
|
|
_timer += Time.deltaTime;
|
|
if (_timer >= longPressTime && !_fired)
|
|
{
|
|
_fired = true;
|
|
_pressing = false;
|
|
|
|
// ⭐ 吞掉松手时的 Toggle 翻转:Toggle.InternalToggle 检查 IsInteractable,
|
|
// 置 false 后 OnPointerClick 不会翻转 isOn;下一帧恢复
|
|
if (_toggle != null && _toggle.interactable)
|
|
{
|
|
_toggle.interactable = false;
|
|
_restoreInteractable = true;
|
|
}
|
|
|
|
onLongPress?.Invoke();
|
|
}
|
|
}
|
|
else if (_restoreInteractable && _toggle != null)
|
|
{
|
|
// 长按吞掉翻转后,下一帧恢复 interactable
|
|
_toggle.interactable = true;
|
|
_restoreInteractable = false;
|
|
}
|
|
}
|
|
|
|
public void OnPointerDown(PointerEventData eventData)
|
|
{
|
|
if (eventData.button != PointerEventData.InputButton.Left) return;
|
|
_pressing = true;
|
|
_timer = 0f;
|
|
_fired = false;
|
|
}
|
|
|
|
public void OnPointerUp(PointerEventData eventData)
|
|
{
|
|
_pressing = false;
|
|
_timer = 0f;
|
|
// 提前松手(未达长按阈值) → 不干预,Toggle 自己处理点击翻转
|
|
}
|
|
}
|