上一篇文章对UI事件监测用的方法是GraphicRaycaster.Raycast能够准确的检测到鼠标的滑入、划出、点击等事件,这篇文章介绍一下另外一种事件监听的方法,这种方法是Unity内部集成的方法,使用起来相对更加方便。EventTrigger组件
直接上代码吧,注释很清楚
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public struct EventCallbackData {
public EventTrigger eventTrigger;
public UnityAction<BaseEventData> callback;
}
public class EventTriggerListener : MonoBehaviour
{
public delegate void MouseEvent(BaseEventData data);
public static Dictionary<string, EventCallbackData> eventDict = new Dictionary<string, EventCallbackData>();
#region 事件管理
/// <summary>
/// 给目标物体添加响应事件
/// </summary>
/// <param name="target">目标物体</param>
/// <param name="type">事件类型</param>
/// <param name="call">响应函数</param>
/// <param name="callId">响应函数的唯一标识符,用于后期移除事件</param>
public static void AddListener(GameObject target, EventTriggerType type, MouseEvent call, string callId = null)
{
if (callId != null && eventDict.ContainsKey(callId))
{
Debug.LogError("响应函数标识符被占用:" + callId);
return;
}
EventTrigger eventTrigger = target.GetComponent<EventTrigger>();
if (!eventTrigger)
{
eventTrigger = target.AddComponent<EventTrigger>();
}
//获取事件列表
List<EventTrigger.Entry> entries = eventTrigger.triggers;
EventTrigger.Entry entry = new EventTrigger.Entry();
bool isExist = false;
for (int i = 0; i < entries.Count; i++)
{
if (entries[i].eventID == type)
{
entry = entries[i];
isExist = true;
}
}
UnityAction<BaseEventData> action = new UnityAction<BaseEventData>(call);
if (callId != null)
{
EventCallbackData data = new EventCallbackData();
data.callback = action;
data.eventTrigger = eventTrigger;
eventDict.Add(callId, data);//添加事件信息进入字典
}
entry.callback.AddListener(action);
if (!isExist)
{
entry.eventID = type;
eventTrigger.triggers.Add(entry);
}
}
/// <summary>
/// 移除指定的事件响应
/// </summary>
/// <param name="type">事件类型</param>
/// <param name="callId">响应函数标识符</param>
public static void RemoveListener(EventTriggerType type, string callId) {
if (!eventDict.ContainsKey(callId))
{
Debug.LogError("事件移除失败!没有找到对应的事件标识符:" + callId);
return;
}
EventCallbackData data = eventDict[callId];
EventTrigger eventTrigger = data.eventTrigger;
EventTrigger.Entry entry = GetEntry(eventTrigger,type);
if (entry!=null)
{
entry.callback.RemoveListener(data.callback);
}
}
/// <summary>
/// 移除某一种事件的所有响应函数
/// </summary>
/// <param name="target">目标物体</param>
/// <param name="type">事件类型</param>
public static void RemoveListeners(GameObject target, EventTriggerType type)
{
EventTrigger eventTrigger = target.GetComponent<EventTrigger>();
EventTrigger.Entry entry = GetEntry(eventTrigger, type);
if (entry != null)
{
entry.callback.RemoveAllListeners();
}
}
/// <summary>
/// 移除物体身上所有的响应事件
/// </summary>
/// <param name="target">目标物体</param>
public static void RemoveAllListeners(GameObject target)
{
EventTrigger eventTrigger = target.GetComponent<EventTrigger>();
if (!eventTrigger)
{
return;
}
//获取事件列表
List<EventTrigger.Entry> entries = eventTrigger.triggers;
for (int i = 0; i < entries.Count; i++)
{
entries[i].callback.RemoveAllListeners();
}
}
/// <summary>
/// 获取指定事件的回调条目对象
/// </summary>
/// <param name="eventTrigger">EventTrigger组件</param>
/// <param name="type">事件类型</param>
/// <returns></returns>
static EventTrigger.Entry GetEntry(EventTrigger eventTrigger,EventTriggerType type) {
if (!eventTrigger)
{
return null;
}
//获取事件列表
List<EventTrigger.Entry> entries = eventTrigger.triggers;
for (int i = 0; i < entries.Count; i++)
{
if (entries[i].eventID == type)
{
return entries[i];
}
}
return null;
}
#endregion
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class UIMgr : MonoBehaviour
{
public GameObject[] mouseDownObjs;
public GameObject[] mouseUpObjs;
public GameObject[] mouseExitObjs;
public GameObject[] mouseEnterObjs;
void Start()
{
AddListener();
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
EventTriggerListener.RemoveListener(EventTriggerType.PointerEnter,"mouseEnter0");
}
}
void AddListener() {
for (int i = 0; i < mouseDownObjs.Length; i++)
{
GameObject obj = mouseDownObjs[i];
EventTriggerListener.AddListener(obj,EventTriggerType.PointerDown,MouseDown);
}
for (int i = 0; i < mouseUpObjs.Length; i++)
{
GameObject obj = mouseUpObjs[i];
EventTriggerListener.AddListener(obj, EventTriggerType.PointerUp, MouseUp);
}
for (int i = 0; i < mouseExitObjs.Length; i++)
{
GameObject obj = mouseExitObjs[i];
EventTriggerListener.AddListener(obj, EventTriggerType.PointerExit, MouseExit);
}
for (int i = 0; i < mouseEnterObjs.Length; i++)
{
GameObject obj = mouseEnterObjs[i];
EventTriggerListener.AddListener(obj, EventTriggerType.PointerEnter, MouseEnter,"mouseEnter"+i);
}
}
public void MouseDown(BaseEventData data)
{
PointerEventData eventData = data as PointerEventData;
Debug.Log("鼠标点击到UI物体:"+eventData.pointerCurrentRaycast);
}
public void MouseUp(BaseEventData data)
{
PointerEventData eventData = data as PointerEventData;
Debug.Log("鼠标释放到UI物体:" + eventData.pointerCurrentRaycast);
}
public void MouseExit(BaseEventData data)
{
PointerEventData eventData = data as PointerEventData;
Debug.Log("鼠标离开UI物体:" + eventData.pointerEnter);
}
public void MouseEnter(BaseEventData data)
{
PointerEventData eventData = data as PointerEventData;
Debug.Log("鼠标进入UI物体:" + eventData.pointerEnter);
}
}