Unity的UGUI,處理滑鼠事件,需要自行實作IPointerClickHandler,IPointerDownHandler等接口,很不友善。
我們可以把常用接口封裝起來,讓需要實作滑鼠事件的類,繼承已經封裝好的類即可。
using System;
using UnityEngine;
using UnityEngine.EventSystems;
public class ClickOnListener : MonoBehaviour, IPointerClickHandler, IPointerDownHandler, IPointerUpHandler {
#region Action
public Action ActClick = delegate {};
public Action ActPress = delegate { };
public Action ActRelease = delegate { };
#endregion
#region Click Event
/// <summary>
/// 當滑鼠點選時
/// </summary>
/// <param name="eventData"></param>
public void OnPointerClick(PointerEventData eventData) {
ActClick();
}
/// <summary>
/// 當滑鼠按下時
/// </summary>
/// <param name="eventData"></param>
public void OnPointerDown(PointerEventData eventData) {
ActPress();
}
/// <summary>
/// 當滑鼠擡起時
/// </summary>
/// <param name="eventData"></param>
public void OnPointerUp(PointerEventData eventData) {
ActRelease();
}
/// <summary>
/// 清除
/// </summary>
public void Clear() {
ActClick = null;
ActPress = null;
ActRelease = null;
}
#endregion
}
如此一來,隻需要讓UI類繼承 ClickOnListener 類,然後注冊 ActClick 等已經封裝好的事件即可,比每次都重複實作接口的效率要高不少。
本例封裝了三個接口,有需要可以把UI事件接口全部封裝起來(見下文)。不過需要注意一個問題,由于這些接口都是空實作,但是隻要寫了這個方法,哪怕沒有實作,Unity的UI消息機制,也會每次将消息發送到這個方法上,會有一定性能開銷。
還可以增加一個靜态接口,用于發送滑鼠事件:
#region Static
/// <summary>
/// 向指定對象發送點選事件
/// </summary>
/// <param name="target">目标</param>
public static void SendOnClick(GameObject target) {
PointerEventData eventData = new PointerEventData(null);
target.SendMessage("OnPointerClick", eventData);
}
#endregion
最後附上一個比較完整的UI事件監聽器類,有需要同時處理較多UI事件的情況可以直接使用。
using UnityEngine;
using UnityEngine.EventSystems;
public class UIEventListener : MonoBehaviour, IPointerClickHandler, IPointerDownHandler, IPointerEnterHandler,
IPointerExitHandler,
IPointerUpHandler, ISelectHandler, IUpdateSelectedHandler, IDeselectHandler, IDragHandler,
IEndDragHandler, IDropHandler, IScrollHandler, IMoveHandler
{
public delegate void UIPointerEventDelegate(GameObject go, PointerEventData data);
public delegate void UIBaseEventDelegate(GameObject go, BaseEventData data);
public delegate void UIAxisEventDelegate(GameObject go, AxisEventData data);
public UIPointerEventDelegate onClick = delegate { };
public UIPointerEventDelegate onDown = delegate { };
public UIPointerEventDelegate onEnter = delegate { };
public UIPointerEventDelegate onExit = delegate { };
public UIPointerEventDelegate onUp = delegate { };
public UIBaseEventDelegate onSelect = delegate { };
public UIBaseEventDelegate onUpdateSelect = delegate { };
public UIBaseEventDelegate onDeSelect = delegate { };
public UIPointerEventDelegate onDrag = delegate { };
public UIPointerEventDelegate onEndDrag = delegate { };
public UIPointerEventDelegate onDrop = delegate { };
public UIPointerEventDelegate onScroll = delegate { };
public UIAxisEventDelegate onMove = delegate { };
/// <summary>
/// 用于對任意UI對象快速擷取UI事件監聽器
/// </summary>
/// <param name="go">對象</param>
/// <returns>結果</returns>
public static UIEventListener Get(GameObject go)
{
return go.GetOrAddComponent<UIEventListener>();
}
public void OnPointerClick(PointerEventData eventData)
{
onClick(gameObject, eventData);
}
public void OnPointerDown(PointerEventData eventData)
{
onDown(gameObject, eventData);
}
public void OnPointerEnter(PointerEventData eventData)
{
onEnter(gameObject, eventData);
}
public void OnPointerExit(PointerEventData eventData)
{
onExit(gameObject, eventData);
}
public void OnPointerUp(PointerEventData eventData)
{
onUp(gameObject, eventData);
}
public void OnSelect(BaseEventData eventData)
{
onSelect(gameObject, eventData);
}
public void OnUpdateSelected(BaseEventData eventData)
{
onUpdateSelect(gameObject, eventData);
}
public void OnDeselect(BaseEventData eventData)
{
onDeSelect(gameObject, eventData);
}
public void OnDrag(PointerEventData eventData)
{
onDrag(gameObject, eventData);
}
public void OnEndDrag(PointerEventData eventData)
{
onEndDrag(gameObject, eventData);
}
public void OnDrop(PointerEventData eventData)
{
onDrop(gameObject, eventData);
}
public void OnScroll(PointerEventData eventData)
{
onScroll(gameObject, eventData);
}
public void OnMove(AxisEventData eventData)
{
onMove(gameObject, eventData);
}
}