UI的点击、拖拽等事件可以用UnityEngine.EventSystems中的接口的方法来实现,或者用已经实现了IPointerEnterHandler、IPointerExitHandler等所有UI事件的类EventTrigger来选择实现。
这里用一个通用类,使用静态方法为UI组件添加EventListener组件,并设置组件的委托方法等,在OnPointerClick等UI方法中实现方法。
1.简单的点击和双击监听
using UnityEngine;
using UnityEngine.EventSystems;
public class UIClickListener : MonoBehaviour, UnityEngine.EventSystems.IPointerClickHandler
{
public delegate void VoidDelegate(GameObject go, PointerEventData eventData);
public VoidDelegate mOnPointerClick = null; //单击
public VoidDelegate mOnDoublePointerClick = null; //双击
public void OnPointerClick(PointerEventData eventData)
{
if (mOnPointerClick != null && eventData.clickCount == 1)
{
mOnPointerClick(gameObject, eventData);
}
if (mOnDoublePointerClick != null && eventData.clickCount == 2)
{
mOnDoublePointerClick(gameObject, eventData);
}
}
static public UIClickListener Get(GameObject go)
{
UIClickListener listener = go.GetComponent<UIClickListener>();
if (listener == null) listener = go.AddComponent<UIClickListener>();
return listener;
}
}
2.包含实现UI全部的点击事件的类,使用委托声明方法,可为GameObject或Transform或其子物体添加
using UnityEngine;
using UnityEngine.EventSystems;
[AddComponentMenu("UIExt/Event Listener")]
public class UIEventListener : UnityEngine.EventSystems.EventTrigger
{
public delegate void VoidEventDelegate();
public delegate void VoidDelegate(GameObject go, PointerEventData eventData);
public delegate void BaseEventDelegate(GameObject go, BaseEventData eventData);
public delegate void AxisEventDelegate(GameObject go, AxisEventData eventData);
public delegate void BoolDelegate(GameObject go, bool press);
public VoidDelegate mOnPointerEnter = null;
public VoidDelegate mOnPointerExit = null;
public VoidDelegate mOnPointerDown = null;
public VoidDelegate mOnPointerUp = null;
public VoidDelegate mOnPointerClick = null;
public VoidDelegate mOnDoublePointerClick = null;
public VoidEventDelegate mOnClick = null;
public BoolDelegate mOnPress = null;
public VoidDelegate mOnDrag = null;
public VoidDelegate mOnDrop = null;
public VoidDelegate mOnBeginDrag = null;
public VoidDelegate mOnEndDrag = null;
public VoidDelegate mOnScroll = null;
public BaseEventDelegate mOnSelect = null;
public BaseEventDelegate mOnDeselect = null;
public AxisEventDelegate mOnMove = null;
public BaseEventDelegate mOnUpdateSelected = null;
public VoidDelegate mOnInitializePotentialDrag = null;
public BaseEventDelegate mOnSubmit = null;
public BaseEventDelegate mOnCancel = null;
override public void OnPointerEnter(PointerEventData eventData)
{
if (mOnPointerEnter != null)
{
mOnPointerEnter(gameObject, eventData);
}
}
override public void OnPointerExit(PointerEventData eventData)
{
if (mOnPointerExit != null)
{
mOnPointerExit(gameObject, eventData);
}
}
override public void OnPointerDown(PointerEventData eventData)
{
if (mOnPointerDown != null)
{
mOnPointerDown(gameObject, eventData);
}
if (mOnPress != null)
{
mOnPress(gameObject, true);
}
}
override public void OnPointerUp(PointerEventData eventData)
{
if (mOnPointerUp != null)
{
mOnPointerUp(gameObject, eventData);
}
if (mOnPress != null)
{
mOnPress(gameObject, false);
}
}
override public void OnPointerClick(PointerEventData eventData)
{
if (mOnPointerClick != null && eventData.clickCount == 1)
{
mOnPointerClick(gameObject, eventData);
}
if (mOnDoublePointerClick != null && eventData.clickCount == 2)
{
mOnDoublePointerClick(gameObject, eventData);
}
if (mOnClick != null)
{
mOnClick();
}
}
override public void OnDrag(PointerEventData eventData)
{
if (mOnDrag != null)
{
mOnDrag(gameObject, eventData);
}
}
override public void OnBeginDrag(PointerEventData eventData)
{
if (mOnBeginDrag != null)
{
mOnBeginDrag(gameObject, eventData);
}
}
override public void OnEndDrag(PointerEventData eventData)
{
if (mOnEndDrag != null)
{
mOnEndDrag(gameObject, eventData);
}
}
override public void OnDrop(PointerEventData eventData)
{
if (mOnDrop != null)
{
mOnDrop(gameObject, eventData);
}
}
override public void OnScroll(PointerEventData eventData)
{
if (mOnScroll != null)
{
mOnScroll(gameObject, eventData);
}
}
override public void OnSelect(BaseEventData eventData)
{
if (mOnSelect != null)
{
mOnSelect(gameObject, eventData);
}
}
override public void OnDeselect(BaseEventData eventData)
{
if (mOnDeselect != null)
{
mOnDeselect(gameObject, eventData);
}
}
override public void OnUpdateSelected(BaseEventData eventData)
{
if (mOnUpdateSelected != null)
{
mOnUpdateSelected(gameObject, eventData);
}
}
override public void OnMove(AxisEventData eventData)
{
if (mOnMove != null)
{
mOnMove(gameObject, eventData);
}
}
override public void OnSubmit(BaseEventData eventData)
{
if (mOnSubmit != null)
{
mOnSubmit(gameObject, eventData);
}
}
override public void OnCancel(BaseEventData eventData)
{
if (mOnCancel != null)
{
mOnCancel(gameObject, eventData);
}
}
override public void OnInitializePotentialDrag(PointerEventData eventData)
{
if (mOnInitializePotentialDrag != null)
{
mOnInitializePotentialDrag(gameObject, eventData);
}
}
static public UIEventListener Get(GameObject go)
{
UIEventListener listener = go.GetComponent<UIEventListener>();
if (listener == null) listener = go.AddComponent<UIEventListener>();
return listener;
}
static public UIEventListener Get(Transform parent, string childName)
{
Transform tran = FindChild(parent, childName);
return Get(tran.gameObject);
}
static private Transform FindChild(Transform parent, string childName)
{
if (childName.Contains("/"))
{
return parent.Find(childName);
}
Transform child = parent.Find(childName);
if (child != null)
{
return child;
}
Transform[] tranArray = parent.GetComponentsInChildren<Transform>(true);
for (int i = 0; i < tranArray.Length; ++i)
{
Transform tran = tranArray[i];
if (tran.name == childName)
{
return tran;
}
}
return null;
}
}
3.UI点击事件会出现的问题就是和ScrollRect的拖拽冲突,还有短时间内多次重复点击会使响应慢的事件多次调用,因此要对这两方面做处理
using System;
using System.Linq;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class EventTriggerListener : EventTrigger
{
public Action<GameObject> OnClickCallback;
public ScrollRect ScrollRect;
public bool IsDragging { get; private set; }
public event Action<GameObject> OnClick;
public event Action<GameObject> OnClickDown;
public object[] objects { get; set; }
public bool IsDelay = true;
private DateTime clickTime;
private int clickNums;
private const float CLICK_DELTATIME = 0.5f;
private const float CLICK_TIMES = 3;
public EventTriggerListener Get(Transform transform)
{
var listener = transform.GetComponent<EventTriggerListener>();
if (listener == null) listener = transform.gameObject.AddComponent<EventTriggerListener>();
if (listener.ScrollRect == null)
listener.ScrollRect = transform.gameObject.GetComponentsInParent<ScrollRect>(true).FirstOrDefault();
return listener;
}
public static EventTriggerListener Get(GameObject go)
{
var listener = go.GetComponent<EventTriggerListener>();
if (listener == null) listener = go.AddComponent<EventTriggerListener>();
if (listener.ScrollRect == null)
listener.ScrollRect = go.GetComponentsInParent<ScrollRect>(true).FirstOrDefault();
return listener;
}
public void SetObjects(params object[] args)
{
objects = args;
}
private void Awake()
{
clickTime = DateTime.Now;
}
public override void OnPointerClick(PointerEventData eventData)
{
base.OnPointerClick(eventData);
if (IsDragging) return;
if (IsDelay)
{
long ts1 = ConvertDateTimeToShortLong(DateTime.Now) - ConvertDateTimeToShortLong(clickTime);
if (ts1 > CLICK_DELTATIME)
{
clickNums = 0;
OnClick?.Invoke(gameObject);
OnClickCallback?.Invoke(gameObject);
}
else
{
clickNums++;
if (clickNums > CLICK_TIMES)
{
//TipManager.Instance.Toast("点击太频繁,请稍后再点击");
}
}
clickTime = DateTime.Now;
}
}
public override void OnPointerDown(PointerEventData eventData)
{
base.OnPointerDown(eventData);
if (IsDragging) return;
OnClickDown?.Invoke(gameObject);
}
public override void OnBeginDrag(PointerEventData eventData)
{
IsDragging = true;
if (ScrollRect == null) return;
ScrollRect.OnBeginDrag(eventData);
}
public override void OnDrag(PointerEventData eventData)
{
IsDragging = true;
if (ScrollRect == null) return;
ScrollRect.OnDrag(eventData);
}
public override void OnEndDrag(PointerEventData eventData)
{
IsDragging = false;
if (ScrollRect == null) return;
ScrollRect.OnEndDrag(eventData);
}
public long ConvertDateTimeToShortLong(DateTime dt)
{
var dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
var toNow = dt.Subtract(dtStart);
var timeStamp = toNow.Ticks;
timeStamp = long.Parse(timeStamp.ToString().Substring(0, timeStamp.ToString().Length - 7));
return timeStamp;
}
}
如未注明 , 均为原创丨欢迎转载,转载请注明原文链接。