Unity-鼠标监测UI事件二(EventTrigger)

咸昀
2023-12-01

鼠标监测UI事件二(EventTrigger)

上一篇文章对UI事件监测用的方法是GraphicRaycaster.Raycast能够准确的检测到鼠标的滑入、划出、点击等事件,这篇文章介绍一下另外一种事件监听的方法,这种方法是Unity内部集成的方法,使用起来相对更加方便。EventTrigger组件

EventTrigger的所有事件类型

  • PointerEnter = 0 鼠标进入
  • PointerExit = 1 鼠标离开
  • PointerDown = 2 鼠标按下
  • PointerUp = 3 鼠标抬起
  • PointerClick = 4 鼠标点击(鼠标抬起时已不在原UI上时不会触发,在PointerUp之后调用)
  • Drag = 5 鼠标拖拽
  • Drop = 6 拖拽结束时鼠标不在被拖拽UI上并且在另外一个UI上时触发(在PointerUp之后)
  • Scroll = 7 滑轮滚动时
  • UpdateSelected = 8 被选中后的每一帧
  • Select = 9 在被选中时
  • Deselect = 10 结束选中时
  • Move = 11 按方向键时
  • InitializePotentialDrag = 12 初始化拖拽(在PointerDown之后,PoinerUp之前调用,点击就会调用)
  • BeginDrag = 13 拖拽开始(鼠标按下不移动不会触发)
  • EndDrag = 14 拖拽结束
  • Submit = 15 默认为Enter键
  • Cancel = 16 默认为Esc键

事件管理类

直接上代码吧,注释很清楚

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

 类似资料: