目录
[TOC]
二、UGUI的事件系统
1.概述
UGUI的事件系统主要由三个部分组成:
- (1)Canvas画布下的Graphic Raycaster图形射线组件:只响应继承有
Graphic
基类的UI元素。 - (2)Event System组件:响应UI事件,也响应3D、2D物体的事件。
- (3)Standalone Input Module独立的输入模型组件:全局唯一存在,处理用户点击输入。
2.Graphic Raycaster图形射线组件
图形射线组件区别于一般的2D、3D物体的射线:
- 图形射线组件:一般情况下只响应继承有
Graphic
图形基类的UI元素 - 2D射线:只响应拥有2DCollider碰撞器的对象
- 3D射线:只响应拥有3DCollider碰撞器的对象
图形射线组件负责控制管理该Canvas画布下所有UI元素的射线交互,例如按钮点击。如果移除或禁用该组件,则和射线相关的交互均会失效。
- Ignore Reversed Graphics:是否忽略反转的图形,顾名思义,如果勾选(默认勾选)则当UI元素
的Rotation中的Y大于90度,即产生了翻转,则不再受图形射线组件控制,即不再有射线交互效果。
- Blocking Objects:阻挡对象,表示哪些对象可以阻挡UI射线。
Three D:3D指的是拥有3D碰撞体的物体,也就是说即使是UI元素,只要其拥有3D碰撞体,在此处也算作3D。
- Blocking Mask:阻挡遮罩,设置哪些层级可以阻挡UI射线。
3.UGUII事件实现的三种方式
- 实现接口
- 编辑界面添加组件
- 代码中添加组件
(1)实现接口(推荐使用)
例如:和拖拽相关的事件。
IInitializePotentialDragHandler
:按下的时候执行一次IBeginDragHandler
:开始拖拽的时候执行一次IDragHandler
:拖拽过程中持续执行多次(此接口必须实现,否则其他拖拽不执行!)IDropHandler
:放下拖拽物体后执行一次IEndDragHandler
:结束拖拽时执行一次(所有拖拽事件中最后执行)
public class UGUIEvent_DragTest : MonoBehaviour, IInitializePotentialDragHandler, IBeginDragHandler, IDragHandler, IDropHandler, IEndDragHandler
{
//按下的时候执行一次
public void OnInitializePotentialDrag(PointerEventData eventData)
{
Debug.Log("OnInitializePotentialDrag");
}
//开始拖拽的时候执行一次
public void OnBeginDrag(PointerEventData eventData)
{
Debug.Log("OnBeginDrag");
}
//拖拽过程中持续执行多次
public void OnDrag(PointerEventData eventData)
{
//Debug.Log("OnDrag");
RectTransform rect = GetComponent<RectTransform>();
Vector3 pos = Vector3.zero;
RectTransformUtility.ScreenPointToWorldPointInRectangle(rect, eventData.position, eventData.enterEventCamera, out pos);
rect.position = pos;
}
//放下拖拽物体后执行一次
public void OnDrop(PointerEventData eventData)
{
Debug.Log("OnDrop");
}
//结束拖拽时执行一次
public void OnEndDrag(PointerEventData eventData)
{
Debug.Log("OnEndDrag");
}
}
(2)编辑界面添加EventTrigger
组件
(3)代码中添加EventTrigger
组件
public class UGUIEventTriggerTest : MonoBehaviour
{
private int mIndex;
private void Start()
{
EventTrigger eventTrigger = gameObject.AddComponent<EventTrigger>();//添加组件
eventTrigger.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());//给事件的回调函数添加监听
eventTrigger.triggers.Add(entry);//添加到列表中
}
public void ChangeColor()
{
if (mIndex == 0)
{
GetComponent<Image>().color = Color.blue;
}
else
{
GetComponent<Image>().color = Color.white;
}
mIndex = mIndex == 0 ? 1 : 0;
}
}
运行时:
4.常见事件接口
(1)拖拽相关:Drag
和Drop
IInitializePotentialDragHandler
:按下的时候执行一次IBeginDragHandler
:开始拖拽的时候执行一次IDragHandler
:拖拽过程中持续执行多次(此接口必须实现,否则其他拖拽不执行!)IDropHandler
:放下拖拽物体后执行一次IEndDragHandler
:结束拖拽时执行一次(所有拖拽事件中最后执行)
(2)点击相关:Pointer
IPointerEnterHandler
:鼠标指针进入时执行一次IPointerExitHandler
:鼠标指针移除时执行一次IPointerDownHandler
:鼠标指针按下时执行一次IPointerUpHandler
:鼠标指针抬起时执行一次IPointerClickHandler
:鼠标指针抬起后执行一次
(3)选中相关:Select
(UI元素需添加Selectable
组件)
ISelectHandler
:第一次点击(选中状态)时执行一次IUpdateSelectedHandler
:选中状态下每帧执行IDeselectHandler
:第二次点击(非选中状态)时执行一次
选中相关事件和点击相关事件的执行先后顺序:
ISelectHandler
=>IPointerDownHandler
=>IUpdateSelectedHandler
=>IPointerUpHandler
=>IPointerClickHandler
=>IDeselectHandler
(4)系统按键相关:Submit
、Cancel
、Move
、Scroll
(UI元素需添加Selectable
组件)
ISubmitHandler
:提交:默认Enter/Space(选中当前UI元素时有效)ICancelHandler
:取消:默认ESC(选中当前UI元素时有效)IMoveHandler
:移动:默认WSAD/上下左右(选中当前UI元素时有效)IScrollHandler
:鼠标滚轮(停留在当前UI元素上时有效)
5.事件参数PointerEventData
clickCount
:连击次数clickTime
:上一次点击的时间(注意:OnPointerClick
中是本次点击的时间)delta
:UI元素移动增量
拖拽的另一种实现方式:
public class UGUIEventDataTest : MonoBehaviour, IPointerDownHandler, IPointerClickHandler, IDragHandler
{
public void OnPointerDown(PointerEventData eventData)
{
//OnPointerDown显示上一次点击的时间
Debug.Log("OnPointerDown:" + eventData.clickTime);
Debug.Log("OnPointerDown:" + eventData.clickCount);
}
public void OnPointerClick(PointerEventData eventData)
{
//OnPointerClick显示本次点击时间
Debug.Log("OnPointerClick:" + eventData.clickTime);
Debug.Log("OnPointerClick:" + eventData.clickCount);
}
//拖拽的另一种实现(真机中可能会出现不一致的问题)
public void OnDrag(PointerEventData eventData)
{
RectTransform rect = GetComponent<RectTransform>();
rect.anchoredPosition += eventData.delta;
}
}