一.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 } }
可以看到,这个类是用于记录事件信息如拖动距离、是否拖动、输入的键信息等的对象模板。所有的事件接口的方法都有且仅有一个PointerEventData类的参数。