UGUI 事件系统

廉价感情. 提交于 2020-03-11 12:20:55

当我们在场景中创建任一UI对象后,Hierarchy面板中都可以看到系统自动创建了EventSystem对象,EventSystem对象负责管理所有事件相关对象,该对象下挂载了EventSystem组件和StandaloneInputModule组件,前者为管理脚本,后者为输入模块。Canvas对象下挂载了GraphicRaycaster负责处理射线相关运算,用户的操作都会通过射线检测来映射到UGUI组件上,InputModule将用户的操作转化为射线检测,Raycaster则找到目标对象并通知EventSystem,最后EventSystem发送事件让目标对象进行响应。
总结来说就是:EventSystem负责管理,BaseInputModule负责输入,BaseRaycaster负责确定目标对象,目标对象负责接收事件并处理,然后一个完整的事件系统就有了


一:EventSystem事件系统


一个场景中只能有一个EventSystem组件
——First Selected:第一次默认选择的物体
——Send Navigation Events:是否可以使用导航事件(键盘上下左右)控制
——Drag Threshold:视为拖拽操作的最小距离

二:EventInterface事件接口


 

(实现Tooltip)
——IPointerEnterHandler
鼠标进入时响应
——IPointerExitHandler
鼠标离开时响应

 

——IPointerDownHandler
在可视元素矩形区域内按下时响应
——IPointerUpHandler
在可视元素矩形区域内按下后,在任意区域抬起时响应
——IPointerClickHandler
在可视元素矩形区域内按下后,在同一可视元素矩形区域内抬起时响应

 

(实现背包物体交换)
——IBeginDragHandler
开始拖动时相应
——IDragHandler
拖动中时相应
——IEndDragHandler
结束拖动时相应
——IDropHandler
接收拖动事件,必须先实现IDragHandler
例子:物体A上实现了IDragHandler,物体B上实现了IDropHandler,从物体A上开始Drag,在物体A上结束Drag,没有触发OnDrop。从物体A上开始Drag,在物体B上结束Drag,可以触发OnDrop
——IInitializePotentialDragHandler
与IPointerDownHandler触发条件大致相同,几乎没用
——IScrollHandler
鼠标滚动滚动时响应

 

——ISelectHandler
每次选择UI元素时响应,但是如果此物体不是Button这种有选择操作的UI元素,需要写代码进行选择:EventSystem.current.SetSelectedGameObject(gameObject)
——IDeselectHandler
每次取消选择UI元素时响应,点击此可视元素矩形区域外即为取消选择
——IUpdateSelectedHandler
选择了UI元素时一直响应

 

(与BuildSettings—PlayerSettings—Input中的设置相对应。与Select相关的三个接口类似也需要元素本身具有选择操作)
——IMoveHandler
与Horizontal和Vertical相对应
——ISubmitHandler
与Submit相对应
——ICancelHandler
与Cancal相对应

三:EventData事件数据


 

——BaseEventData:基础事件数据—事件数据的基类

 


——PointerEventData:光标事件数据—鼠标与触摸的相关数据(进入,点击,拖动),UGUI的大部分事件数据的类型都是PointerEventData
1.button:鼠标的(左,中,右)键哪个键点击的
2.clickCount:连续点击的次数(从1开始累加)
3.clickTime:当前点击的时间(根据上一次点击的时间累加)
4.position:鼠标当前的位置
5.pressPosition:鼠标点击时的位置
6.delta:当前点击与上一次点击的位置差值
7.dragging:是否为拖拽状态(不受EventSystem组件上Drag Threshold的影响,只在使用OnDrag相关事件接口时才起作用)
8.pointerEnter:鼠标进入时的物体
9.pointerPress:鼠标点击时的物体(OnPointerDown,OnPointerEnter等没有鼠标抬起的事件不能使用,因为没有抬起并不算一次点击)
10.pointerDrag:鼠标拖拽的物体
11.lastPress:最后一次点击的物体
12.rawPointerPress:第一次点击的物体
13.worldNormal:射线检测到的第一个物体的法线
14.enterEventCamera:鼠标进入时的相机
15.pressEventCamera:鼠标点击时的相机
16.pointerCurrentRaycast:鼠标进入时的射线信息
17.pointerPressRaycast:鼠标点击时的射线信息

 


——AxisEventData:轴向事件数据—手柄和键盘中控制轴向的相关数据(参考BuildSettings—PlayerSettings—Input中的设置)

四:Raycaster射线检测


UGUI的射线检测是从摄像机发起的并配合碰撞器

必须与Canvas组件一起挂载在同一物体身上
1.Ignore Reversed Graphics:忽略颠倒的图形的射线检测,即旋转180°后的图片不会与射线发生检测
2.Blocking Objects:屏蔽指定类型的物理(必须添加碰撞器)对象,使它们不参与射线检测(渲染模式不为Overlay并添加渲染相机时起作用)
3.Blocking Mask:使屏蔽对象中的指定层不参与射线检测(渲染模式不为Overlay并添加渲染相机且Blocking Objects不为None时起作用)

 

——PhysicsRaycaster和Physics2DRaycaster

必须与Camera组件一起挂载在同一物体身上,给挂载了Camera物体的同一物体添加PhysicsRaycaster组件就可以让3D物体利用EventSystem响应事件了
1.Event Mask::屏蔽指定层不参与射线检测
————————————————
版权声明:本文为CSDN博主「LLLLL__」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/LLLLL__/article/details/104008976

 

IPointerEnterHandler
指针进入
public void OnPointerEnter(PointerEventData eventData);

IPointerExitHandler
指针退出
public void OnPointerExit(PointerEventData eventData);

IPointerDownHandler
指针按下
public void OnPointerDown(PointerEventData eventData);

IPointerUpHandler
指针释放(可能按下时的指针位置跟释放时的指针位置不同,这里指的是按下时指针指着的物体)
public void OnPointerUp(PointerEventData eventData);

IPointerClickHandler
在同一物体上按下并释放
public void OnPointerClick(PointerEventData eventData);

IInitializePotentialDragHandler
拖拽时的初始化,跟IPointerDownHandler差不多,在按下时调用 
public void OnInitializePotentialDrag(PointerEventData eventData);

IBeginDragHandler
开始拖拽
public void OnBeginDrag(PointerEventData eventData);

IDragHandler
拖拽中
public void OnDrag(PointerEventData eventData);

IEndDragHandler
拖拽结束(被拖拽的物体调用)
public void OnEndDrag(PointerEventData eventData);

IDropHandler
拖拽结束(拖拽结束后的位置(即鼠标位置)如果有物体,则那个物体调用)
public void OnDrop(PointerEventData eventData);

IScrollHandler
滚轮滚动
public void OnScroll(PointerEventData eventData);

IUpdateSelectedHandler
被选中的物体每帧调用
public void OnUpdateSelected(BaseEventData eventData);

ISelectHandler
物体被选中时(EventSystem.current.SetSelectedGameObject(gameObject))
public void OnSelect(BaseEventData eventData);

IDeselectHandler
物体从选中到取消选中时
public void OnDeselect(BaseEventData eventData);

IMoveHandler
物体移动时(与InputManager里的Horizontal和Vertica按键相对应),前提条件是物体被选中
public void OnMove(AxisEventData eventData);

ISubmitHandler
提交按钮被按下时(与InputManager里的Submit按键相对应,PC上默认的是Enter键),前提条件是物体被选中
public void OnSubmit(BaseEventData eventData);

ICancelHandler
取消按钮被按下时(与InputManager里的Cancel按键相对应,PC上默认的是Esc键),前提条件是物体被选中
public void OnCancel(BaseEventData eventData);


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
总结:
1.共有17个接口方法
2.其中OnMove使用的参数是AxisEventData eventData
3.其中OnUpdateSelected、OnSelect 、OnDeselect 、OnSubmit 、OnCancel 使用的参数是BaseEventData eventData
4.其余使用的参数是PointerEventData eventData
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
实现事件的两种方式:
1.编辑器:添加Event Trigger组件
2.代码:继承EventTrigger,实现方法(EventTrigger继承了上面所说的接口)

using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
 
public class TestUI3 : MonoBehaviour
{
    private GameObject button;
    private GameObject image;
 
    void Start () 
    {
        button = GameObject.Find("Button");
        image = GameObject.Find("Image");
        EventTriggerListener.GetListener(button).onPointerClick += Click;
        EventTriggerListener.GetListener(image).onDrag += Drag;
    }
 
    public void Click(GameObject go)
    {
        Debug.Log(go.name);
    }
 
    public void Drag(GameObject go)
    {
        Debug.Log(go.name);
    }
}

using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
 
public class EventTriggerListener : EventTrigger
{
    #region 变量
    //带参数是为了方便取得绑定了UI事件的对象  
    public delegate void PointerEventDelegate(GameObject go, PointerEventData eventData);
    public delegate void BaseEventDelegate(GameObject go, BaseEventData eventData);
    public delegate void AxisEventDelegate(GameObject go, AxisEventData eventData);
 
    public event PointerEventDelegate onPointerEnter;
    public event PointerEventDelegate onPointerExit;
    public event PointerEventDelegate onPointerDown;
    public event PointerEventDelegate onPointerUp;
    public event PointerEventDelegate onPointerClick;
    public event PointerEventDelegate onInitializePotentialDrag;
    public event PointerEventDelegate onBeginDrag;
    public event PointerEventDelegate onDrag;
    public event PointerEventDelegate onEndDrag;
    public event PointerEventDelegate onDrop;
    public event PointerEventDelegate onScroll;
    public event BaseEventDelegate onUpdateSelected;
    public event BaseEventDelegate onSelect;
    public event BaseEventDelegate onDeselect;
    public event AxisEventDelegate onMove;
    public event BaseEventDelegate onSubmit;
    public event BaseEventDelegate onCancel;
    #endregion
 
    public static EventTriggerListener GetListener(GameObject go)
    {
        EventTriggerListener listener = go.GetComponent<EventTriggerListener>();
        if (listener == null) listener = go.AddComponent<EventTriggerListener>();
        return listener;
    }
 
    #region 方法
    public override void OnPointerEnter(PointerEventData eventData)
    {
        if (onPointerEnter != null) onPointerEnter(gameObject, eventData);
    }
    public override void OnPointerExit(PointerEventData eventData)
    {
        if (onPointerExit != null) onPointerExit(gameObject, eventData);
    }
    public override void OnPointerDown(PointerEventData eventData)
    {
        if (onPointerDown != null) onPointerDown(gameObject, eventData);
    }
    public override void OnPointerUp(PointerEventData eventData)
    {
        if (onPointerUp != null) onPointerUp(gameObject, eventData);
    }
    public override void OnPointerClick(PointerEventData eventData)
    {
        if (onPointerClick != null) onPointerClick(gameObject, eventData);
    }
    public override void OnInitializePotentialDrag(PointerEventData eventData)
    {
        if (onInitializePotentialDrag != null) onInitializePotentialDrag(gameObject, eventData);
    }
    public override void OnBeginDrag(PointerEventData eventData)
    {
        if (onBeginDrag != null) onBeginDrag(gameObject, eventData);
    }
    public override void OnDrag(PointerEventData eventData)
    {
        if (onDrag != null) onDrag(gameObject, eventData);
    }
    public override void OnEndDrag(PointerEventData eventData)
    {
        if (onEndDrag != null) onEndDrag(gameObject, eventData);
    }
    public override void OnDrop(PointerEventData eventData)
    {
        if (onDrop != null) onDrop(gameObject, eventData);
    }
    public override void OnScroll(PointerEventData eventData)
    {
        if (onScroll != null) onScroll(gameObject, eventData);
    }
    public override void OnUpdateSelected(BaseEventData eventData)
    {
        if (onUpdateSelected != null) onUpdateSelected(gameObject, eventData);
    }
    public override void OnSelect(BaseEventData eventData)
    {
        if (onSelect != null) onSelect(gameObject, eventData);
    }
    public override void OnDeselect(BaseEventData eventData)
    {
        if (onDeselect != null) onDeselect(gameObject, eventData);
    }
    public override void OnMove(AxisEventData eventData)
    {
        if (onMove != null) onMove(gameObject, eventData);
    }
    public override void OnSubmit(BaseEventData eventData)
    {
        if (onSubmit != null) onSubmit(gameObject, eventData);
    }
    public override void OnCancel(BaseEventData eventData)
    {
        if (onCancel != null) onCancel(gameObject, eventData);
    }
    #endregion
}

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!