Unity给UI添加点击事件

博客介绍了通过继承点击事件接口重写点击事件的方法。其好处是方便管理、添加和移除点击事件。阐述了UI分为渲染、点击事件、资源加载层,介绍了点击事件父类、各事件组件类、UI层组件层和事件控制器的作用,还提及相关代码及使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

给UI添加点击事件

前言

这里我们所说的不是button.click = myClick 这种方式。而是通过继承点击事件接口,自己重写一个点击事件出来
这个的好处在于方便管理点击事件,方便添加移除点击事件。

思想

UI中一共分为渲染层,点击事件层,资源加载层。
首先我们需要一个点击事件父类,它用于设置,触发指定类型的点击事件
然后就是各事件组件类,继承该父类。其中有包括点击事件,拖拽事件,双击事件等。本案例中只举例点击事件。
接下来就是我们的UI层组件层,它负责点击事件的操作:添加,移除事件监听,触发事件,添加点击事件组件
最后是事件控制器。枚举所有的点击事件类型,枚举所有的点击事件对应的事件组件。根据事件类型枚举查找事件组件等。

代码

  • 点击事件基类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class UIEvtCompBase : MonoBehaviour {

   /// <summary>
   /// 事件UI
   /// </summary>
   [SerializeField]
   protected UIBaseCommpoent eui;			//UI的组件,因为组件是要挂载在它的身上的
   /// <summary>
   /// 设置事件UI
   /// </summary>
   public void SetEUI(UIBaseCommpoent e)
   {
       eui = e;
   }

   /// <summary>
   /// 触发事件
   /// </summary>
   /// <param name="evtType"></param>
   /// <param name="evtData"></param>
   protected void TriggerUiEvt(UiEvtEnum evtType, BaseEventData evtData)
   {
       if (eui == null)
       {
           eui = GetComponent<UIBaseCommpoent>();
           if (eui == null)
               return;
       }
       eui.DispatchEvent(evtType, evtData);
   }
}
  • 事件组件类
using System;
using UnityEngine.EventSystems;
/// <summary>
/// 普通点击事件组件
/// </summary>
public class CommonEvtComp : UIEvtCompBase, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler, IPointerDownHandler, IPointerUpHandler
{
   /// <summary>
   /// 点击事件
   /// </summary>
   /// <param name="eventData">事件数据</param>
   public virtual void OnPointerClick(PointerEventData eventData)
   {
       TriggerUiEvt(UiEvtEnum.Click, eventData);
   }
   /// <summary>
   /// 鼠标移入
   /// </summary>
   /// <param name="eventData">事件数据</param>
   public virtual void OnPointerEnter(PointerEventData eventData)
   {
       TriggerUiEvt(UiEvtEnum.MouseIn, eventData);
   }
   /// <summary>
   /// 鼠标移出
   /// </summary>
   /// <param name="eventData">事件数据</param>
   public virtual void OnPointerExit(PointerEventData eventData)
   {
       TriggerUiEvt(UiEvtEnum.MouseOut, eventData);
   }
   /// <summary>
   /// 按下
   /// </summary>
   /// <param name="eventData"></param>
   public void OnPointerDown(PointerEventData eventData)
   {
       TriggerUiEvt(UiEvtEnum.PointerDown, eventData);
   }
   /// <summary>
   /// 弹起
   /// </summary>
   /// <param name="eventData"></param>
   public void OnPointerUp(PointerEventData eventData)
   {
       TriggerUiEvt(UiEvtEnum.PointerUp, eventData);
   }
}
  • UI事件数据类
public class UIEvtData
{
   public TouchCallback touchCallback;		//这个是点击事件的回调函数,在事件控制器中有具体的写法
   public System.Object param;				//点击事件监听时传的参数
   public UIEvtData(TouchCallback touchCallback,System.Object param)
   {
       this.touchCallback = touchCallback;
       this.param = param;
   }
   public void CallBack()
   {
       touchCallback(param);
   }
}
  • UI组件类
/// <summary>
/// UI点击事件层
/// </summary>
public class UIBaseCommpoent : MonoBehaviour
{

   /// <summary>
   /// 监听的事件字典
   /// </summary>
   protected Dictionary<UiEvtEnum, List<UIEvtData>> uiEvtDic;

   /// <summary>
   /// 事件组件类型-组件
   /// </summary>
   protected Dictionary<Type, UIEvtCompBase> uiEvtCompDic;

   //1,

   /// <summary>
   /// 触发点击事件
   /// </summary>
   /// <param name="evtType"></param>
   /// <param name="evtData"></param>
   public void DispatchEvent(UiEvtEnum evtType, BaseEventData evtData)
   {
       List<UIEvtData> list = null;
       if(uiEvtDic == null)
       {
           uiEvtDic = new Dictionary<UiEvtEnum, List<UIEvtData>>();
       }
       if(uiEvtDic.TryGetValue(evtType,out list))
       {
           foreach (UIEvtData eventItem in list)
           {
               eventItem.CallBack();
           }
       }
   }

   /// <summary>
   /// 添加监听事件
   /// </summary>
   /// <param name="evtType">事件类型枚举</param>
   /// <param name="func">回调函数</param>
   /// <param name="attachParam">附加参数</param>
   public virtual void AddEventListener(UiEvtEnum evtType, TouchCallback func, System.Object attachParam = null)
   {
       List<UIEvtData> list = null;
       if (uiEvtDic == null)
       {
           uiEvtDic = new Dictionary<UiEvtEnum, List<UIEvtData>>();
       }
       Type t = UIEventCtrl.GetCompByEvt(evtType);
       if (t != null)
       {
           if (uiEvtCompDic == null)
               uiEvtCompDic = new Dictionary<Type, UIEvtCompBase>();
           UIEvtCompBase comp = null;
           uiEvtCompDic.TryGetValue(t, out comp);
           if(comp == null)
           {
               comp = gameObject.AddComponent(t) as UIEvtCompBase;		//添加点击事件
               uiEvtCompDic.Add(t, comp);														//点击事件添加到字典中,不会重复添加
           }
       }
       uiEvtDic.TryGetValue(evtType, out list);									//一个按钮会有多个事件监听,所以用list存储
       if (list == null)
       {
           list = new List<UIEvtData>();
           uiEvtDic.Add(evtType, list);
       }
       list.Add(new UIEvtData(func, attachParam));

   }
   /// <summary>
   /// 移除监听事件
   /// </summary>
   /// <param name="evtType">事件类型枚举</param>
   /// <param name="func">回调函数</param>
   /// <param name="attachParam">附加参数</param>
   public virtual void RemoveEventListener(UiEvtEnum evtType, TouchCallback func, System.Object attachParam = null)
   {
       List<UIEvtData> list = null;
       if (uiEvtDic.TryGetValue(evtType, out list))
       {
           for(int i = 0; i < list.Count; i++)
           {
               if (func == list[i].touchCallback)
               {
                   list.RemoveAt(i);
                   break;
               }
           }
       }
   }
}
using System;
/// <summary>
/// 事件类型枚举
/// </summary>
public enum UiEvtEnum
{
   None = 0,
   /// <summary>
   /// 点击事件
   /// </summary>
   Click,
   /// <summary>
   /// 鼠标移入事件
   /// </summary>
   MouseIn,
   /// <summary>
   /// 鼠标移出事件
   /// </summary>
   MouseOut,
   /// <summary>
   /// 按下
   /// </summary>
   PointerDown,
   /// <summary>
   /// 弹起
   /// </summary>
   PointerUp,
   /// <summary>
   /// 列表(MList)节点数量改变事件
   /// </summary>
   ItemNumChange,
   /// <summary>
   /// 列表(MList)节点索引改变事件
   /// </summary>
   ItemIndexChange,
   /// <summary>
   /// 列表(MList)节点点击事件
   /// </summary>
   ItemClick,
   /// <summary>
   /// 数据改变事件
   /// </summary>
   ValueChange,
   /// <summary>
   /// 链接点击事件
   /// </summary>
   link,
   /// <summary>
   /// 结束事件
   /// </summary>
   complete,
   /// <summary>
   /// 开始拖拽
   /// </summary>
   BeginDrag,
   /// <summary>
   /// 拖拽
   /// </summary>
   Drag,
   /// <summary>
   /// 结束拖拽
   /// </summary>
   EndDrag,
   /// <summary>
   /// 接收到来自其他控件的拖拽
   /// </summary>
   ReceiveDragFrom,
   /// <summary>
   /// 状态改变
   /// </summary>
   StateChange,
   /// <summary>
   /// 长按
   /// </summary>
   LongPress,
   /// <summary>
   /// 获得焦点
   /// </summary>
   GetFocused,
   /// <summary>
   /// 失去焦点
   /// </summary>
   LossFocused
}

/// <summary>
/// 点击事件回调
/// </summary>
/// <param name="value">响应所传的参数表</param>
/// <param name="attachParam"></param>
public delegate void TouchCallback(object attachParam);

public class UIEventCtrl {

   /// <summary>
   /// 事件类型-脚本
   /// </summary>
   public static Type[] uiEvtTypes = new Type[] {
           null
           , typeof(CommonEvtComp)
           , typeof(CommonEvtComp)
           , typeof(CommonEvtComp)
           , typeof(CommonEvtComp)
           , typeof(CommonEvtComp)
           , null
           , null
           , null
           , null
           , null
           , null
           , typeof(DragEvtComp)
           , typeof(DragEvtComp)
           , typeof(DragEvtComp)
           , null
           , null
       };
   /// <summary>
   /// UI事件管理
   /// </summary>
   public UIEventCtrl()
   { }
   /// <summary>
   /// 根据事件类型获得对应的脚本类型
   /// </summary>
   /// <param name="evtType">事件类型</param>
   /// <returns>脚本类型</returns>
   public static Type GetCompByEvt(UiEvtEnum evtType)
   {
       return uiEvtTypes[(int)evtType];
   }
}

使用

   mImage.AddEventListener(UiEvtEnum.Click, Touch, "初始数据");
   mImage.RemoveEventListener(UiEvtEnum.Drag, Touch);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值