• UI中的事件系统EventSystem


    一.EventSystem简介

      用于处理事件的分发和相应的系统,创建画布的同时会创建事件系统

     二.UGUI实现事件系统的3种方式

    1.使用组件eventTrigger(不推荐),拖动赋值

    2.代码添加enentTrigger组件,添加监听的方式

        private int _index;
        // Start is called before the first frame update
        void Start()
        {
            //添加trigger组件
            EventTrigger trigger = gameObject.AddComponent<EventTrigger>();
            //初始化一个事件列表
            trigger.triggers = new List<EventTrigger.Entry>();
    
            //定义绑定类型
            EventTrigger.Entry entry = new EventTrigger.Entry();
            entry.eventID = EventTriggerType.PointerClick;
            //添加事件监听方法
            entry.callback = new EventTrigger.TriggerEvent();
            entry.callback.AddListener((data) => ChangeColor());    //添加的方法必须带有基础数据参数data,目前data为空
    
            //将entry添加到trigger上去
            trigger.triggers.Add(entry);
        }
    
        //供注册使用的方法
        public void ChangeColor()
        {
            if(_index == 0)
            {
                GetComponent<Image>().color = Color.blue;
            }
            else
            {
                GetComponent<Image>().color = Color.red;
            }
            _index = _index == 0 ? 1 : 0;
        }

    可以看到,Entry和TriggerEvent都是EventTrigger组件中的内部类,对应着绑定事件的类型和监听方法,Entry类中含有TriggerEvent类型的变量名称是callback。在添加好事件的类型和回调方法后将entry添加到EventTrigger的事件列表triggers上去。下面是源码中EventTrigger的代码:

    namespace UnityEngine.EventSystems
    {
        [AddComponentMenu("Event/Event Trigger")]
        public class EventTrigger : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler, IPointerDownHandler, IPointerUpHandler, IPointerClickHandler, IInitializePotentialDragHandler, IBeginDragHandler, IDragHandler, IEndDragHandler, IDropHandler, IScrollHandler, IUpdateSelectedHandler, ISelectHandler, IDeselectHandler, IMoveHandler, ISubmitHandler, ICancelHandler
        {
            protected EventTrigger();
    
            public List<Entry> triggers { get; set; }
            [EditorBrowsable(EditorBrowsableState.Never)]
            [Obsolete("Please use triggers instead (UnityUpgradable) -> triggers", true)]
            public List<Entry> delegates { get; set; }
    
            public virtual void OnBeginDrag(PointerEventData eventData);
            public virtual void OnCancel(BaseEventData eventData);
            public virtual void OnDeselect(BaseEventData eventData);
            public virtual void OnDrag(PointerEventData eventData);
            public virtual void OnDrop(PointerEventData eventData);
            public virtual void OnEndDrag(PointerEventData eventData);
            public virtual void OnInitializePotentialDrag(PointerEventData eventData);
            public virtual void OnMove(AxisEventData eventData);
            public virtual void OnPointerClick(PointerEventData eventData);
            public virtual void OnPointerDown(PointerEventData eventData);
            public virtual void OnPointerEnter(PointerEventData eventData);
            public virtual void OnPointerExit(PointerEventData eventData);
            public virtual void OnPointerUp(PointerEventData eventData);
            public virtual void OnScroll(PointerEventData eventData);
            public virtual void OnSelect(BaseEventData eventData);
            public virtual void OnSubmit(BaseEventData eventData);
            public virtual void OnUpdateSelected(BaseEventData eventData);
    
            public class TriggerEvent : UnityEvent<BaseEventData>
            {
                public TriggerEvent();
            }
            public class Entry
            {
                public EventTriggerType eventID;
                public TriggerEvent callback;
    
                public Entry();
            }
        }
    }

    从源码中也可以发现,EventTrigger本质上是通过接口的方式实现的事件,可以理解为这个类是对事件接口实现事件的方式的封装类。

    3.使用接口

    观察上方的EventTrigger的源码,可以发现实现了非常多的接口,这些接口就是事件接口:

    public class EventTrigger : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler, IPointerDownHandler, IPointerUpHandler, IPointerClickHandler, IInitializePotentialDragHandler, IBeginDragHandler, IDragHandler, IEndDragHandler, IDropHandler, IScrollHandler, IUpdateSelectedHandler, ISelectHandler, IDeselectHandler, IMoveHandler, ISubmitHandler, ICancelHandler
    

    这些接口的方法的实现:

     下面我们分类介绍这些接口

    拖动事件的接口:(值得注意的是,没有IDragHandler接口其他3个接口的实现方法不会被执行,因此必须继承IDragHandler接口)

    IInitializePotentialDragHandler:初始化拖动事件,初始化时执行一次

    IBeginDragHandler:开始拖动时执行一次

    IDragHandler:拖动的过程中不断执行

    IEndDragHandler:结束拖动时执行一次

    放下事件的接口:(同样的,要想IDropHandler接口的方法被执行,必须同时实现IDragHandler)

    IDropHandler:在物体拖动后被放下时执行一次

    鼠标指针事件的接口:(一次鼠标点击,可以触发down、up、click3个事件,事件执行顺序也是down、up、click)

    IPointerClickHandler:物体接受点击时执行一次

    IPointerEnterHandler:鼠标指针进入物体范围时执行一次

    IPointerExitHandler:鼠标指针移除物体范围时执行一次

    IPointerDownHandler:鼠标按下时执行一次

    IPointerUpHandler:鼠标抬起时执行一次

    选中事件的接口:

    ISelectHandler:物体被选中时执行一次

    IUpdateSelectedHandler:物体是被选中状态不断执行

    IDeselectHandler:物体结束选中状态时执行一次

    按键事件的接口:

    IScrollHandler:鼠标的滚轮滚动时执行

    ISubmitHandler:提交键按下时执行

    ICancelHandler:取消键按下后执行

    IMoveHandler:方向键等按下后执行

    三.接口的方法参数类型PointerEventData

    下面是这个类的源码:

    public class PointerEventData : BaseEventData
        {
            public List<GameObject> hovered;
    
            public PointerEventData(EventSystem eventSystem);
    
            public GameObject pointerPress { get; set; }
            public Camera pressEventCamera { get; }
            public Camera enterEventCamera { get; }
            public InputButton button { get; set; }
            public bool dragging { get; set; }
            public bool useDragThreshold { get; set; }
            public Vector2 scrollDelta { get; set; }
            public int clickCount { get; set; }
            public float clickTime { get; set; }
            [Obsolete("Use either pointerCurrentRaycast.worldNormal or pointerPressRaycast.worldNormal")]
            public Vector3 worldNormal { get; set; }
            [Obsolete("Use either pointerCurrentRaycast.worldPosition or pointerPressRaycast.worldPosition")]
            public Vector3 worldPosition { get; set; }
            public Vector2 pressPosition { get; set; }
            public Vector2 delta { get; set; }
            public Vector2 position { get; set; }
            public int pointerId { get; set; }
            public bool eligibleForClick { get; set; }
            public RaycastResult pointerPressRaycast { get; set; }
            public RaycastResult pointerCurrentRaycast { get; set; }
            public GameObject pointerDrag { get; set; }
            public GameObject rawPointerPress { get; set; }
            public GameObject lastPress { get; }
            public GameObject pointerEnter { get; set; }
    
            public bool IsPointerMoving();
            public bool IsScrolling();
            public override string ToString();
    
            public enum InputButton
            {
                Left = 0,
                Right = 1,
                Middle = 2
            }
            public enum FramePressState
            {
                Pressed = 0,
                Released = 1,
                PressedAndReleased = 2,
                NotChanged = 3
            }
        }

    可以看到,这个类是用于记录事件信息如拖动距离、是否拖动、输入的键信息等的对象模板。

  • 相关阅读:
    echarts之tooltip
    js随笔
    在wex5平台grid显示问题
    JSON.parse()和JSON.stringify()区别
    在wex5平台grid里面的gridselect下拉不能显示汉字问题
    wex5平台放入tabs组件后运行时显示空白
    正整数求n不用sqrt
    leetcode1143最长公共子序列
    美团Java一面(2020.3.19)
    leetcode138. 复制带随机指针的链表
  • 原文地址:https://www.cnblogs.com/movin2333/p/14311021.html
Copyright © 2020-2023  润新知