Unity中UGUI事件系统(一)

Unity中UGUI事件系统是一个核心组件,它负责处理用户输入事件并将其传递给相应的UI元素。以下是关于UGUI事件系统的详细概述:

一、事件系统概述

  • 定义:事件系统是一个根据输入(如鼠标、键盘、触摸等)将消息发送给对象的系统。

  • 核心组件:事件系统主要由三个组件协同完成,即Event SystemInput ModuleRaycaster

+ `Event System`:主要用来管理当前处于选中状态的游戏对象、当前正在使用的输入模块和射线发射器。
+ `Input Module`:主要用来处理输入、管理事件状态、将事件发送给场景中的对象。
+ `Raycaster`:用于确定鼠标指针位于哪个对象上方。Unity默认提供了三种射线发射器,分别是`Graphic Raycaster`(用于UI元素)、`Physics 2D Raycaster`(用于2D物理元素)和`Physics Raycaster`(用于3D物理元素)。

 

二、事件系统的工作原理

  • 射线检测:通过射线检测来确定用户输入事件发生的位置,并将事件传递给最合适的UI元素。

  • 事件类型:UGUI系统将UI可能触发的事件分为12个类型,这些类型对应于EventTriggerType枚举的12个值,如PointerEnterPointerExitPointerDownPointerUpPointerClick等。

三、实现事件的三种方式

  1. 通过接口实现:Unity提供了许多事件接口,开发者可以在UI元素的脚本中实现这些接口,并在特定动作时触发对应方法。例如,实现IDragHandler接口可以实现UI元素的拖拽效果。

  2. 通过Event Trigger组件实现:为UI元素添加一个Event Trigger组件,并添加对应的事件类型。然后,将开发者自己实现的脚本方法绑定到Event Trigger中,即可在指定动作时触发。

  3. 程序动态设置实现:通过C#代码动态地设置和绑定事件。这允许开发者在运行时根据需要更改绑定的事件。

四、EventSystem组件的常用属性和函数

  • 常用属性

    • firstSelectedGameObject:设置默认选中的UI元素。

    • sendNavigationEvents:是否发送导航事件。

    • pixelDragThreshold:拖拽事件的像素阈值。

    • currentInputModule:当前使用的输入模块。

  • 常用函数

    • SetSelectedGameObject(GameObject selected):设置当前选中的UI元素。

    • RaycastAll(PointerEventData eventData, List<RaycastResult> resultAppendList):执行射线检测,并将结果保存到指定的列表中。

    • UpdateModules():更新输入模块。

UGUI事件系统实践

通过Event Trigger组件手动实现拖动UI功能

1. 给目标UI添加EventTrigger组件并且添加Drag(拖动)事件

2. 给Drag 添加事件List,并挂载UIEventSys脚本到Runtime Only,选择触发事件后将要执行的函数

 

using UnityEngine;

namespace umbella.UIEvent
{
    public class UIEventSys : MonoBehaviour
    {
        public void dragUITarget()
        {
            Debug.Log("将要对UITarget拖动");
        }
    }
}

 

 

3. 启动游戏,我们尝试拖动UI,虽然UI没有被我们拖动了(因为我们没有写具体逻辑),但是执行了我们自定义的拖动函数。  

通过接口实现拖动UI功能(一)

UIEventDrag脚本挂载到需要移动的UI上。

UIEventDrag 脚本必须实现MonoBehaviour, IDragHandler, IInitializePotentialDragHandler, IBeginDragHandler, IEndDragHandler等接口。其中核心接口在于IDragHandler, IInitializePotentialDragHandler,否则IBeginDragHandler, IEndDragHandler 将无法执行。

using UnityEngine;
using UnityEngine.EventSystems;

public class UIEventDrag:MonoBehaviour,IDragHandler,IInitializePotentialDragHandler,IBeginDragHandler,IEndDragHandler
{

    public void OnInitializePotentialDrag(PointerEventData eventData)
    {
        Debug.Log("初始化可能的拖动事件");
    }

    public void OnBeginDrag(PointerEventData eventData)
    {
       Debug.Log("开始拖动");
    }

    public void OnDrag(PointerEventData eventData)
    {
        Debug.Log("拖动");
        RectTransform rec = GetComponent<RectTransform>(); //获取UI 中基础组件RectTransform
        Vector3 pos; //申明Vector3 结构体来接收UI物体移动的世界坐标
        //rec 是UI的RectTransform组件(UI移动全靠它为基础),eventData.position 鼠标移动的位置(屏幕坐标),eventData.enterEventCamera 哪个照相机照射的
        // out pos 输出UI游戏物体对象 转换后的世界坐标
        RectTransformUtility.ScreenPointToWorldPointInRectangle(rec, eventData.position, eventData.enterEventCamera,
           out pos);
        //设置UI 世界空间位置
        rec.position = pos;
    }
    public void OnEndDrag(PointerEventData eventData)
    {
        Debug.Log("结束拖动");
    }
}

 

通过接口实现拖动UI功能(二)

UIEventDrag脚本挂载到需要移动的UI上。

using UnityEngine;
using UnityEngine.EventSystems;

public class UIEventDrag:MonoBehaviour,IDragHandler,IDropHandler
{
    public void OnDrag(PointerEventData eventData)
    {
        Debug.Log("拖动");
        RectTransform rec = GetComponent<RectTransform>(); //获取UI 中基础组件RectTransform
        Vector3 pos; //申明Vector3 结构体来接收UI物体移动的世界坐标
        //rec 是UI的RectTransform组件(UI移动全靠它为基础),eventData.position 鼠标移动的位置(屏幕坐标),eventData.enterEventCamera 哪个照相机照射的
        // out pos 输出UI游戏物体对象 转换后的世界坐标
        RectTransformUtility.ScreenPointToWorldPointInRectangle(rec, eventData.position, eventData.enterEventCamera,
           out pos);
        //设置UI 世界空间位置
        rec.position = pos;
    }
    public void OnDrop(PointerEventData eventData)
    {
        Debug.Log("UI游戏物体放下");
    }
}

运行游戏

通过接口实现拖动UI功能(三)

1. 添加脚本UIEventDrag并挂载到目标UI上

using UnityEngine;
using UnityEngine.EventSystems;

public class UIEventDrag:MonoBehaviour,IDragHandler
{

    public void OnDrag(PointerEventData eventData)
    {
        //获取UI的RectTransform组件
        RectTransform rectTransform = GetComponent<RectTransform>();
        //根据UI事件系统传来的参数eventData.delta 来改变 RectTransform组件锚点位置,实现拖动功能
        rectTransform.anchoredPosition += eventData.delta;
        Debug.Log("UI被拖动了");
    }
}

 

2. 运行游戏

通过接口实现点击UI功能(一)

实现接口IPointerClickHandler(鼠标点击)、IPointerEnterHandler(鼠标进入)、IPointerExitHandler(鼠标移出)、IPointerDownHandler(鼠标按下)、IPointerUpHandler(鼠标松开)、UIEventClick脚本挂载到需要点击的UI上。

using UnityEngine;
using UnityEngine.EventSystems;

public class UIEventClick : MonoBehaviour,IPointerClickHandler,IPointerEnterHandler,IPointerExitHandler,IPointerDownHandler,IPointerUpHandler
{
    public void OnPointerClick(PointerEventData eventData)
    {
        Debug.Log("鼠标点击了UI");
    }

    public void OnPointerEnter(PointerEventData eventData)
    {
        Debug.Log("鼠标进入UI");
    }

    public void OnPointerExit(PointerEventData eventData)
    {
        Debug.Log("鼠标退出UI");
    }

    public void OnPointerDown(PointerEventData eventData)
    {
        Debug.Log("鼠标按下了UI");
    }

    public void OnPointerUp(PointerEventData eventData)
    {
        Debug.Log("鼠标松开了UI");
    }
}

运行游戏  

通过接口实现选中UI功能(一)

1. 添加UIEventSelect脚本,该脚本实现了ISelectHandler(选定),IUpdateSelectedHandler(选中),IDeselectHandler(未选中)。

using UnityEngine;
using UnityEngine.EventSystems;

public class UIEventSelect : MonoBehaviour,ISelectHandler,IUpdateSelectedHandler,IDeselectHandler
{
    public void OnSelect(BaseEventData eventData)
    {
        Debug.Log("选定了UI");
    }

    public void OnUpdateSelected(BaseEventData eventData)
    {
        Debug.Log("选中UI中");
    }

    public void OnDeselect(BaseEventData eventData)
    {
        Debug.Log("未选定UI");
    }
}

2. 添加Selectable组件

3. 运行游戏

通过接口实现常见键盘操作UI功能(一)

1.添加脚本UIEventSysKey在目标UI上,并且添加Selectable组件、IScrollHandler(鼠标滚轮),ISubmitHandler(Enter/空格键),ICancelHandler(ECS键),IMoveHandler(方向键)

using UnityEngine;
using UnityEngine.EventSystems;

public class UIEventSysKey : MonoBehaviour,IScrollHandler,ISubmitHandler,ICancelHandler,IMoveHandler
{
    public void OnScroll(PointerEventData eventData)
    {
        Debug.Log("滑动了鼠标滚轮");
    }

    public void OnSubmit(BaseEventData eventData)
    {
        Debug.Log("按下了Enter/空格键");
    }

    public void OnCancel(BaseEventData eventData)
    {
        Debug.Log("按下了ECS键");
    }

    public void OnMove(AxisEventData eventData)
    {
        Debug.Log("按下了方向键(WSAD、上下左右键)");
    }
}

 

 2. 运行游戏

 


想获取更多学习资源,可以关注公众号:脚本开发者,或者加入unity交流q群:115885644,我们一起学习,一起成长~  

 

 

 

 

 

 

 

  • 35
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值