主要功能说明:
- 长按检测:通过记录指针按下的时间,判断是否达到
longClickTime
,从而触发长按事件。 - 状态管理:使用
StateEnum
枚举管理点击项的当前状态(未按下、按下等待长按、长按已触发)。 - 事件回调:通过实现
IPointerDownHandler
、IPointerUpHandler
和ICancelHandler
接口,处理 Unity UI 的指针事件。 - 监听器事件:用于定义长按事件的监听器,外部类可以注册事件以处理长按逻辑。
使用场景:
- 适用于需要检测长按操作的 UI 元素,例如长按删除、长按编辑等交互场景。
/****************************************************
文件:LongClickable.cs
作者:Edision
日期:#CreateTime#
功能:长按
*****************************************************/
using UnityEngine;
using UnityEngine.UI;
using System;
using UnityEngine.EventSystems;
/// <summary>
/// 用于将“长按点击”事件委托给事件监听器
/// 需要一个可点击的图形组件(可以是透明度为零的图像)以接收 OnPointerDown、OnPointerUp 等事件。
/// 其他 UI 元素不应覆盖此组件,以确保能够接收指针回调。
/// </summary>
[RequireComponent(typeof(Graphic))]
public class LongClickable : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
{
public float longClickTime = .7f; // 用户需要按住点击的时间(秒)以触发长按事件
public event Action<LongClickable> OnLongClick; // 定义长按事件
public StateEnum State { get { return _State; } } // 当前点击项的状态
float _PressedTime; // 指针按下时的时间
StateEnum _State; // 当前点击项的状态
/// <summary>
/// 枚举表示点击项的不同状态
/// </summary>
public enum StateEnum
{
NOT_PRESSING, // 未按下
PRESSING_WAITING_FOR_LONG_CLICK, // 按下,等待是否触发长按
PRESSING_AFTER_LONG_CLICK // 按下,长按已触发
}
/// <summary>
/// 每帧调用,用于检查是否达到长按时间
/// </summary>
void Update()
{
if (_State == StateEnum.PRESSING_WAITING_FOR_LONG_CLICK)
{
// 检查自指针按下以来的时间是否超过长按时间
if (Time.unscaledTime - _PressedTime >= longClickTime)
{
_State = StateEnum.PRESSING_AFTER_LONG_CLICK; // 更新状态以指示长按已触发
OnLongClick?.Invoke(this); // 触发长按事件
}
}
}
#region Unity UI 事件处理回调
/// <summary>
/// 当指针按下时调用
/// </summary>
/// <param name="eventData">与指针事件相关的数据</param>
public void OnPointerDown(PointerEventData eventData)
{
if (eventData.button != PointerEventData.InputButton.Left) // 确保仅处理左键点击
return;
_State = StateEnum.PRESSING_WAITING_FOR_LONG_CLICK; // 更新状态以指示项被按下
_PressedTime = Time.unscaledTime; // 记录指针按下的时间
}
/// <summary>
/// 当指针松开时调用
/// </summary>
/// <param name="eventData">与指针事件相关的数据</param>
public void OnPointerUp(PointerEventData eventData)
{
if (eventData.button != PointerEventData.InputButton.Left) // 确保仅处理左键松开
return;
_State = StateEnum.NOT_PRESSING; // 更新状态以指示项未被按下
}
#endregion
}
/****************************************************
文件:LongClickableItem.cs
作者:Edision
日期:#CreateTime#
功能:UI 元素
*****************************************************/
using UnityEngine;
[RequireComponent(typeof(LongClickable))]
public class LongClickableItem : MonoBehaviour
{
private void Awake()
{
LongClickable item = GetComponent<LongClickable>();
item.OnLongClick += HandleLongClick;
}
void HandleLongClick(LongClickable clickedItem)
{
Debug.Log("长按事件触发!");
}
}