Unity--UI的Event事件

Unity–UI的Event事件

0.简介

UI作为交互的重要使者, 他需要不断的响应玩家的交互–按下,松开,点击,双击,长按等事件.

Unity中的UI事件系统是一个强大的框架,允许开发者创建交互式的用户界面。它基于事件驱动模型,意味着UI元素可以触发事件,而开发者可以编写代码来响应这些事件。UI事件系统特别适用于处理用户输入,如鼠标点击、触摸、拖拽等。

1.主要特点:

  1. 事件监听器:通过为UI元素添加事件监听器,可以捕获并响应特定的事件。
  2. 事件调度:Unity的事件系统负责事件的分发,确保正确的事件被发送到正确的监听器。
  3. 模块化:可以轻松地为不同的UI元素添加或移除事件监听器,从而创建动态和响应式的用户界面。
  4. 自定义事件:除了Unity内置的事件类型外,开发者还可以定义自己的事件类型。

2.常用UI事件:

  • 点击(Click):当用户点击UI元素时触发。
  • 双击(DoubleClick):当用户快速连续两次点击UI元素时触发。
  • 按下(Down):当用户按下鼠标按钮或触摸屏幕时触发。
  • 松开(Up):当用户释放鼠标按钮或停止触摸屏幕时触发。
  • 进入(Enter):当指针(鼠标或触摸点)进入UI元素的边界时触发。
  • 离开(Exit):当指针离开UI元素的边界时触发。
  • 拖拽(Drag):当用户在UI元素上拖拽时触发。

3.使用UI事件:

  1. 添加UI组件:首先,在UI元素(如按钮、图像等)上添加相应的UI组件。
  2. 实现事件接口:在脚本中,实现相应的事件接口,如IPointerClickHandler
  3. 添加事件监听器:在脚本中,为UI元素添加事件监听器。
  4. 处理事件:在接口方法中编写代码来处理事件。

4.具体步骤

1.命名空间

需要引入命名空间 UnityEngine.EventSystems;

using UnityEngine.EventSystems;
2.自带的UI事件拆解

在Unity的UGUI中自带的一些组件中(例如: Image, Button)含有基本的UI响应事件, 例如Button的按下事件, 我们一般使用的通过OnClick添加按下按钮的监听事件AddListener, 即 button.OnClick.AddListener(响应函数名). 但是这是Unity为我们封装好的函数. 因此,如果想要自己实现自定义的交互事件,或者自己手动写一个Button脚本,就需要我们探索. 而Unity提供了基础的接口以便我们实现.

举一个简单的例子: 上文中,Unity中创建的Button我们可以通过添加OnClick.AddListener的方式添加点击后的效果, 但是仔细思考一下. 鼠标的点击分为按下松开. 因此我们自己写一个Button的点击事件,需要拆分为鼠标按下响应事件和鼠标松开响应事件. 如果你需要长按鼠标,3s,需要记录按下与松开之间的时间(该时间可以是秒数也可以是帧数)

3.鼠标按下帧检测

回到鼠标按下和松开例子中, 鼠标按下是后什么时候松开呢? 为了检测鼠标松开 ,计算机需要实时检测鼠标的按下状态, 这里的实时指的每一帧. 在每一帧中检测鼠标的状态,如果鼠标的状态发生改变,就调用对应的的函数. 为了检测鼠标的状态是否发生改变, 我们可以使用枚举类定义鼠标的各种状态, 例如: 按下--0, 松开--1, 按下并松开--3, 没有改变--4. 在Unity中以下是鼠标的按下状态检测枚举. 当然,VR中就是手柄的按下.

public enum FramePressState
{
    Pressed = 0,
    Released = 1,
    PressedAndReleased = 2,
    NotChanged = 3
}
4.常用接口

因此, 要自定一些效果,长按,短按, 滑动,双击,三击,需要我们自己实现. 或者使用现成的插件.

在Unity中常用的接口有:

鼠标进入, 鼠标移出, 鼠标按下, 鼠标抬起, 获得鼠标的的位置, 获取鼠标按下按键索引值(左键, 右键,中键)

对应的接口名称如下

  • IPointerEnterHandler:当指针进入UI元素时触发。
  • IPointerExitHandler:当指针离开UI元素时触发。
  • IPointerDownHandler:当指针在UI元素上按下时触发。
  • IPointerUpHandler:当指针在UI元素上松开时触发。
  • IPointerClickHandler:当指针在UI元素上点击时触发。
  • IPointerDoubleClickHandler:当指针在UI元素上双击时触发。

5.实践代码

所以, 只要继承了接口,我们就可以实现自己想要的功能. 例如以下代码是实现了一张图片简单模拟按钮的功能, 实现了基础的鼠标进入,鼠标移出,鼠标按下,鼠标松开的自定义功能,修改了图片的颜色

using UnityEngine.EventSystems;

public class UIEvent : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerDownHandler, IPointerUpHandler
{

    private Image imgButton;							// 图片
    private Color originalColor;						// 图片的原始颜色
    private Color hoverColor;							// 鼠标进入的颜色
    private Color pressColor;							// 鼠标按下的颜色
    private Color unpressColor;							// 鼠标松开的颜色


    void Start()
    {
        imgButton = this.transform.gameObject.GetComponent<Image>();
        originalColor = imgButton.color;
        hoverColor = new Color(0, 0, 127, 0.5f);
        pressColor = new Color(255, 255, 255, 0.5f);
        unpressColor = new Color(0, 0, 0, 0.5f);
    }

    // 鼠标进入的接口实现
    public void OnPointerEnter(PointerEventData eventData)
    {
        Debug.Log("鼠标进入 " + "鼠标坐标:  x=" + eventData.position.x + " y=" +eventData.position.y);
        // 改变图片颜色
        imgButton.color = hoverColor;
    }

    // 鼠标离开的接口实现
    public void OnPointerExit(PointerEventData eventData)
    {
        Debug.Log("鼠标离开 " + "鼠标坐标:  x=" + eventData.position.x + " y=" + eventData.position.y);
        imgButton.color = originalColor;
    }

    // 鼠标抬起的接口实现 
    public void OnPointerUp(PointerEventData eventData)
    {
        Debug.Log("鼠标松开 松开按键为:" + eventData.pointerId);
        imgButton.color = unpressColor;
    }

    // 鼠标按下的接口实现
    public void OnPointerDown(PointerEventData eventData)
    {
        Debug.Log("鼠标按下 按下按键为:" + eventData.pointerId);
        imgButton.color = pressColor;
    }
}

6.PointerEventData

在上面的代码中, 我们发现每一个接口实现中都有一个参数eventData, 该参数是一个PointerEventData 的类型, 根据名称我们能大致推断出, 该参数包含了鼠标/指针(这里的指针不是这程序中的指针)的相关数据. 通过查看代码,我们能够发现里面的有很多方法. 以下是所有的方法. 根据返回的类型不同,我们可以获得具体的信息.

#region 程序集 UnityEngine.UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// 项目名\Library\ScriptAssemblies\UnityEngine.UI.dll
#endregion

using System;
using System.Collections.Generic;

namespace UnityEngine.EventSystems
{
    public class PointerEventData : BaseEventData
    {
        public List<GameObject> hovered;

        public PointerEventData(EventSystem eventSystem);

        public bool dragging { get; set; }				// 是否处于退拽中
        public InputButton button { get; set; }
        public float pressure { get; set; }				// 按下的压力
        public float tangentialPressure { get; set; }	 // 触摸屏的侧压力
        public float altitudeAngle { get; set; }		// 触摸屏与笔的角度--可以调整画笔的粗细或压力
        public float azimuthAngle { get; set; }			// 触摸笔的旋转角度
        public float twist { get; set; }
        public Vector2 tilt { get; set; }
        public PenStatus penStatus { get; set; }
        public Vector2 radius { get; set; }
        public Vector2 radiusVariance { get; set; }
        public bool fullyExited { get; set; }			// 鼠标完全移出
        public bool reentered { get; set; }				// 鼠标重新进入
        public Camera enterEventCamera { get; }
        public Camera pressEventCamera { get; }
        public GameObject pointerPress { get; set; }
        public bool useDragThreshold { get; set; }
        public Vector2 scrollDelta { get; set; }
        public int clickCount { get; set; }
        public float clickTime { get; set; }
        public GameObject pointerEnter { get; set; }
        public GameObject lastPress { get; }
        public GameObject rawPointerPress { get; set; }
        public GameObject pointerDrag { get; set; }
        public GameObject pointerClick { get; set; }
        public RaycastResult pointerPressRaycast { get; set; }
        public RaycastResult pointerCurrentRaycast { get; set; }
        public int pointerId { get; set; }				// 说的鼠标点击的按键索引值
        public Vector2 position { get; set; }			// 鼠标当前的屏幕坐标
        public Vector2 delta { get; set; }
        public Vector2 pressPosition { get; set; }		// 鼠标按下的坐标
        [Obsolete("Use either pointerCurrentRaycast.worldPosition or pointerPressRaycast.worldPosition")]
        public Vector3 worldPosition { get; set; }
        [Obsolete("Use either pointerCurrentRaycast.worldNormal or pointerPressRaycast.worldNormal")]
        public Vector3 worldNormal { get; set; }
        public bool eligibleForClick { 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
        }
    }
}
  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值