Files
5.24BuYu/Assets/MyGame/aa/UI/Game/Sub/ToggleLongPress.cs
T
2026-09-21 16:39:08 +08:00

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 自己处理点击翻转
}
}