天天看點

【Unity3D / UI】 快速處理滑鼠事件的方法

    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);
	}
}