1. EventTriggerListener
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class EventTriggerListener : EventTrigger
{
public delegate void VoidDelegate(GameObject go);
public delegate void BoolDelegate(GameObject go, bool state);
public delegate void FloatDelegate(GameObject go, float delta);
public delegate void VectorDelegate(GameObject go, Vector2 delta);
public delegate void ObjectDelegate(GameObject go, GameObject obj);
public delegate void KeyCodeDelegate(GameObject go, KeyCode key);
public delegate void EventDataDelegate(PointerEventData eventData);
public VoidDelegate onClick;
public VoidDelegate onDown;
public VoidDelegate onEnter;
public VoidDelegate onExit;
public VoidDelegate onUp;
public VoidDelegate onSelect;
public VoidDelegate onUpdateSelect;
public EventDataDelegate onDrag;
public EventDataDelegate onBeginDrag;
public EventDataDelegate onEndDrag;
public EventDataDelegate onDrop;
static public EventTriggerListener Get(GameObject go)
{
EventTriggerListener listener = go.GetComponent<EventTriggerListener>();
if (listener == null) listener = go.AddComponent<EventTriggerListener>();
return listener;
}
static public EventTriggerListener Get(Transform transform)
{
EventTriggerListener listener = transform.GetComponent<EventTriggerListener>();
if (listener == null) listener = transform.gameObject.AddComponent<EventTriggerListener>();
return listener;
}
public override void OnPointerClick(PointerEventData eventData)
{
if (onClick != null && !eventData.dragging) onClick(gameObject);
}
public override void OnPointerDown(PointerEventData eventData)
{
if (onDown != null) onDown(gameObject);
}
public override void OnPointerEnter(PointerEventData eventData)
{
if (onEnter != null) onEnter(gameObject);
}
public override void OnPointerExit(PointerEventData eventData)
{
if (onExit != null) onExit(gameObject);
}
public override void OnPointerUp(PointerEventData eventData)
{
if (onUp != null) onUp(gameObject);
}
public override void OnSelect(BaseEventData eventData)
{
if (onSelect != null) onSelect(gameObject);
}
public override void OnUpdateSelected(BaseEventData eventData)
{
if (onUpdateSelect != null) onUpdateSelect(gameObject);
}
public override void OnDrag(PointerEventData eventData)
{
if (onDrag != null) onDrag(eventData);
}
public override void OnBeginDrag(PointerEventData eventData)
{
if (onBeginDrag != null) onBeginDrag(eventData);
}
public override void OnEndDrag(PointerEventData eventData)
{
if (onEndDrag != null) onEndDrag(eventData);
}
public override void OnDrop(PointerEventData eventData)
{
if (onDrop != null) onDrop(eventData);
}
}
2、按钮长按事件处理
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class ButtonPress : Button
{
public bool isPointerDown = false;
private float timePressStarted;
private float durationThreshold = 0.2f; // 长按的阈值时间
public UnityEvent OnPress = new UnityEvent(); // 长按事件
public UnityEvent OnPressEnd = new UnityEvent(); // 长按结束事件
private void Update()
{
if (isPointerDown)
{
if (Time.time - timePressStarted > durationThreshold)
{
OnPress.Invoke();
}
}
}
public override void OnPointerDown(PointerEventData eventData)
{
base.OnPointerDown(eventData);
if (eventData.button != PointerEventData.InputButton.Left)
return;
timePressStarted = Time.time;
isPointerDown = true;
}
public override void OnPointerUp(PointerEventData eventData)
{
base.OnPointerUp(eventData);
isPointerDown = false;
OnPressEnd.Invoke();
}
}
上述代码ButtonPress
也可改为继承自MonoBehaviour
,通过挂接的方式实现,而不是替换Button
组件,可降低侵入性。
3、按钮长按、双击等多种事件合集
using System;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class ExButton : Button
{
private enum EnumExButtonState
{
/// <summary>空</summary>
None,
/// <summary>鼠标按下</summary>
PointerDown,
/// <summary>鼠标按下</summary>
PointerUp,
/// <summary>单击</summary>
Click,
/// <summary>双击</summary>
DoubleClick,
/// <summary>长按开始</summary>
PressBegin,
/// <summary>长按</summary>
Press,
/// <summary>长按结束</summary>
PressEnd,
}
/// <summary>按钮状态</summary>
private EnumExButtonState mButtonState = EnumExButtonState.None;
/// <summary>鼠标按下时间</summary>
private float mPointerDownTime = 0.0f;
[SerializeField]
/// <summary>双击间隔时间</summary>
private float mDoubleClickInterval = 0.2f;
[SerializeField]
/// <summary>长按开始时间</summary>
private float mPressBeginTime = 0.3f;
[SerializeField]
/// <summary>长按间隔时间,0为每帧调用</summary>
private float mPressIntervalTime = 0.2f;
/// <summary>长按缓存时间</summary>
private float mPressCacheTime = 0f;
public Action OnClick { get; set; }
public Action OnDoubleClick { get; set; }
public Action OnPressBegin { get; set; }
public Action OnPress { get; set; }
public Action OnPressEnd { get; set; }
public override void OnPointerDown(PointerEventData eventData)
{
base.OnPointerDown(eventData);
if (OnDoubleClick != null)
{
if (mButtonState == EnumExButtonState.None)
{
mButtonState = EnumExButtonState.PointerDown;
mPointerDownTime = Time.time;
}
else if (mButtonState == EnumExButtonState.PointerUp)
{
if (Time.time - mPointerDownTime < mDoubleClickInterval)
{
mButtonState = EnumExButtonState.DoubleClick;
return;
}
else
{
mButtonState = EnumExButtonState.PointerDown;
mPointerDownTime = Time.time;
}
}
}
if (OnPressBegin != null || OnPress != null || OnPressEnd != null)
{
if (mButtonState != EnumExButtonState.DoubleClick)
{
mButtonState = EnumExButtonState.PointerDown;
mPointerDownTime = Time.time;
}
}
if (OnClick != null)
{
mButtonState = EnumExButtonState.PointerDown;
}
}
public override void OnPointerUp(PointerEventData eventData)
{
base.OnPointerUp(eventData);
if (OnDoubleClick != null)
{
if (mButtonState == EnumExButtonState.PointerDown)
{
mButtonState = EnumExButtonState.PointerUp;
return;
}
else if (mButtonState == EnumExButtonState.DoubleClick)
{
return;
}
}
if (OnPressBegin != null || OnPress != null || OnPressEnd != null)
{
if (mButtonState == EnumExButtonState.Press)
{
mButtonState = EnumExButtonState.PressEnd;
return;
}
}
if (OnClick != null)
{
if (mButtonState == EnumExButtonState.PointerDown)
mButtonState = EnumExButtonState.PointerUp;
}
}
private void Update()
{
ProcessUpdate();
ResponseButtonState();
}
private void ProcessUpdate()
{
if (OnDoubleClick != null) { }
if (OnPressBegin != null || OnPress != null || OnPressEnd != null)
{
if (mButtonState == EnumExButtonState.PointerDown)
{
if (Time.time - mPointerDownTime > mPressBeginTime)
{
mButtonState = EnumExButtonState.PressBegin;
mPressCacheTime = 0f;
return;
}
}
}
if (OnClick != null)
{
if (mButtonState == EnumExButtonState.PointerUp)
{
if (OnDoubleClick != null)
{
if (Time.time - mPointerDownTime > mDoubleClickInterval)
mButtonState = EnumExButtonState.Click;
}
else
{
mButtonState = EnumExButtonState.Click;
}
}
}
}
private void ResponseButtonState()
{
switch (mButtonState)
{
case EnumExButtonState.None:
break;
case EnumExButtonState.Click:
OnClick?.Invoke();
mButtonState = EnumExButtonState.None;
break;
case EnumExButtonState.DoubleClick:
OnDoubleClick?.Invoke();
mButtonState = EnumExButtonState.None;
break;
case EnumExButtonState.PressBegin:
OnPressBegin?.Invoke();
mButtonState = EnumExButtonState.Press;
break;
case EnumExButtonState.Press:
{
mPressCacheTime += Time.deltaTime;
if (mPressCacheTime >= mPressIntervalTime)
{
mPressCacheTime = mPressCacheTime - mPressIntervalTime;
OnPress?.Invoke();
}
break;
}
case EnumExButtonState.PressEnd:
OnPressEnd?.Invoke();
mButtonState = EnumExButtonState.None;
break;
default:
break;
}
}
}