EventSystem详解.md

本文深入探讨Unity中EventSystem组件的功能与工作原理,包括处理输入、射线投射及事件分发。介绍EventSystem与BaseInputModule、BaseRaycaster组件的交互机制,以及如何响应各种UI事件。

EventSystem

处理输入、射线和发送事件。
在Unity场景中EventSystem主要负责加工和处理事件,一个场景只能有一个EentSystem

EventSystem类

静态属性:
current :获取当前的EventSystem
EventSystem里面有一个List,current会返回第一个EventSystem

属性
currentSelectedGameObject:当前属于活动状态的物体
firstSelectedGameObject: 最先被选中的GameObject

公开方法:
IsPointerOverGameObject:鼠标点击的物体是否在EventSystem对象上

示例:检测点击的是否是UI

如果使用不带参数的IsPointerOverGameObject(),则它指向“鼠标左键”(pointerId = -1); 因此,当您使用IsPointerOverGameObject进行触摸时,应考虑将指标指标传递给它
请注意,对于触摸而言,IsPointerOverGameObject应该与OnMouseDown()或Input.GetMouseButtonDown(0)或Input.GetTouch(0).phase == TouchPhase.Began一起使用。

         public class MouseExample : MonoBehaviour
         {
             void Update()
             {
                 // Check if the left mouse button was clicked
                 if (Input.GetMouseButtonDown(0))
                 {
                     // Check if the mouse was clicked over a UI element
                     if (EventSystem.current.IsPointerOverGameObject())
                     {
                         Debug.Log("Clicked on the UI");
                     }
                 }
             }

RaycastAll:将所有已配置的BaseRaycaster投射到场景当中

示例:执行UI物体之下的点击事件

public void ExecuteAll(PointerEventData eventData)
    {
        List<RaycastResult> results = new List<RaycastResult>();
        EventSystem.current.RaycastAll(eventData,results);
        foreach (var result in results)
        {
            if (result.gameObject !=gameObject)
            {
                ExecuteEvents.Execute(result.gameObject, eventData, ExecuteEvents.pointerClickHandler);
            }
        }
    }

UpdateModules:重新计算内部的BaseInputModule列表

EventSystem对象创建说明

当在场景中年创建任一UI,系统会自动创建EventSystem,并且带有EventSystem,StandloneInputModule,TouchInputModule三个组件,后两个组件都继承BaseInputModule。

EventSystem在一开始的时候会把自己所属对象下的BaseInputModule类型组件加到一个内部列表,并且在每个Update周期通过接口UpdateModules接口调用这些基本输入模块的UpdateModule接口,然后BaseInputModule会在UpdateModule接口中将自己的状态修改成’Updated’,之后BaseInputModule的Process接口才会被调用。

BaseInputModule是一个基类模块,负责发送输入事件(点击、拖拽、选中等)到具体对象。EventSystem下的所有输入模块都必须继承自BaseInputModule组件。StandaloneInputModule和TouchInputModule组件是系统提供的标准输入模块和触摸输入模块,我们可以通过继承BaseInputModule实现自己的输入模块。

除了以上两个组件,还有一个很重要的组件通过EventSystem对象我们看不到,它是BaseRaycaster组件。BaseRaycaster也是一个基类,前面说的输入模块要检测到鼠标事件必须有射线投射组件才能确定目标对象。系统实现的射线投射类组件有PhysicsRaycaster, Physics2DRaycaster, GraphicRaycaster。这个模块也是可以自己继承BaseRaycaster实现个性化定制。

总的来说,EventSystem负责管理,BaseInputModule负责输入,BaseRaycaster负责确定目标对象,目标对象负责接收事件并处理,然后一个完整的事件系统就有了。

在这里插入图片描述

响应事件

1、输入模块可以检测到的事件

StandaloneInputModule和TouchInputModule两个组件会检测一些输入操作,以事件的方式(message系统)通知目标对象,那么这两个组件支持的事件主要有以下:

  • IPointerEnterHandler - OnPointerEnter - Called when a pointer enters the object
  • IPointerExitHandler - OnPointerExit - Called when a pointer exits the object
  • IPointerDownHandler - OnPointerDown - Called when a pointer is pressed on the object
  • IPointerUpHandler - OnPointerUp - Called when a pointer is released (called on the original the pressed object)
  • IPointerClickHandler - OnPointerClick - Called when a pointer is pressed and released on the same object
  • IInitializePotentialDragHandler - OnInitializePotentialDrag - Called when a drag target is found, can be used to initialise values
  • IBeginDragHandler - OnBeginDrag - Called on the drag object when dragging is about to begin
  • IDragHandler - OnDrag - Called on the drag object when a drag is happening
  • IEndDragHandler - OnEndDrag - Called on the drag object when a drag finishes
  • IDropHandler - OnDrop - Called on the object where a drag finishes
  • IScrollHandler - OnScroll - Called when a mouse wheel scrolls
  • IUpdateSelectedHandler - OnUpdateSelected - Called on the selected object each tick
  • ISelectHandler - OnSelect - Called when the object becomes the selected object
  • IDeselectHandler - OnDeselect - Called on the selected object becomes deselected
  • IMoveHandler - OnMove - Called when a move event occurs (left, right, up, down, ect)
  • ISubmitHandler - OnSubmit - Called when the submit button is pressed
  • ICancelHandler - OnCancel - Called when the cancel button is pressed

包括Button等的点击事件,都是靠实现这些接口进行事件分发的。

我们可以自行继承接口实现监听,也可以通过EventTrigger组件进行监听事件。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RZdR7oav-1577688040935)(index_files/f82e00c0-a8e8-40cf-9cd0-7268e269e2af.jpg)]

示例:自定义继承EventTrigger实现常用监听,无需挂载脚本

public class EventTriggerListener : UnityEngine.EventSystems.EventTrigger
{
    public delegate void VoidDelegate(GameObject go);

    public VoidDelegate OnClick;
    public VoidDelegate OnDown;
    public VoidDelegate OnEnter;
    public VoidDelegate OnExit;
    public VoidDelegate OnUp;
    public VoidDelegate OnSelected;
    public VoidDelegate OnUpdateSelect;


    /// <summary>
    /// 得到“监听器”组件
    /// </summary>
    /// <param name="go">监听的游戏对象</param>
    /// <returns>
    /// 监听器
    /// </returns>
    public static EventTriggerListener Get(GameObject go)
    {
        EventTriggerListener lister = go.GetComponent<EventTriggerListener>();
        if (lister == null)
        {
            lister = go.AddComponent<EventTriggerListener>();
        }

        return lister;
    }

    public override void OnPointerClick(PointerEventData eventData)
    {
        OnClick?.Invoke(gameObject);
    }

    public override void OnPointerDown(PointerEventData eventData)
    {
        OnDown?.Invoke(gameObject);
    }

    public override void OnPointerEnter(PointerEventData eventData)
    {
        OnEnter?.Invoke(gameObject);
    }

    public override void OnPointerExit(PointerEventData eventData)
    {
        OnExit?.Invoke(gameObject);
    }

    public override void OnPointerUp(PointerEventData eventData)
    {
        OnUp?.Invoke(gameObject);
    }

    public override void OnSelect(BaseEventData eventBaseData)
    {
        OnSelected?.Invoke(gameObject);
    }

    public override void OnUpdateSelected(BaseEventData eventBaseData)
    {
        OnUpdateSelect?.Invoke(gameObject);
    }
} //Class_end

监听使用:

 protected  void RigisterButtonObjectEvent(GameObject goButton, EventTriggerListener.VoidDelegate delHandle)
    {
        //给按钮注册事件方法
        if (goButton != null)
        {
            EventTriggerListener.Get(goButton).OnClick = delHandle;        }
    }

最后,要想详细分析Ugui EventSystem,可以阅读源码,这里有一篇对EventSystem源码解析的文章。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

KindSuper_liu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值