首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Unity3D实现UI的单击、双击、拖动状态判断

Unity3D实现UI的单击、双击、拖动状态判断

作者头像
心疼你的一切
发布2026-01-20 14:11:55
发布2026-01-20 14:11:55
1120
举报
文章被收录于专栏:人工智能人工智能

👉一、 前言

博客将会介绍Unity3D实现UI的单击、双击、拖动状态判断 希望这篇博客对Unity的开发者有所帮助。 大家好,我是心疼你的一切,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 欢迎点赞评论哦.下面就让我们进入正文吧 ! 这篇文章就来实现UI的单击、双击、按压、拖动的不同状态判断。不定时更新Unity开发技巧,觉得有用记得一键三连哦。

👉二、鼠标的点击事件

👉2-1 鼠标输入的API

示例、

代码语言:javascript
复制
       if (Input.GetMouseButtonDown (0))  //左键点击
        {

        }
        if (Input.GetMouseButtonDown(1))  //右键点击
        {

        }
        if (Input.GetMouseButtonDown(2))  //中键点击
        {

        }

判断单击和双击,主要是判断点击的次数。

👉三、UI的点击事件

👉3-1 UI点击事件API

UI的点击事件,需要继承UI的点击事件接口,重写点击事件即可。 UI点击事件接口:

代码语言:javascript
复制
public class Btn_OnClick : MonoBehaviour,IPointerClickHandler,IPointerDownHandler,IPointerUpHandler,IPointerExitHandler
👉3-1-1 所引用的命名空间
代码语言:javascript
复制
using UnityEngine.EventSystems;

👉3-2 代码如下

示例:

代码语言:javascript
复制
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class Btn_OnClick : MonoBehaviour,IPointerClickHandler,IPointerDownHandler,IPointerUpHandler,IPointerExitHandler
{
    public void OnPointerClick(PointerEventData eventData) //鼠标点击UI
    {
       
    }

    public void OnPointerDown(PointerEventData eventData) //鼠标按下UI
    {
      
    }

    public void OnPointerExit(PointerEventData eventData) //鼠标离开UI
    {
       
    }

    public void OnPointerUp(PointerEventData eventData)//鼠标点击UI后抬起
    {
        
    }
 }

知道了API,下面就在这个基础上进行修改

👉四、使用步骤

👉4-1 实现UI的单价、双击、按压、拖动的不同状态判断

代码如下(示例):

代码语言:javascript
复制
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using UnityEngine.Events;

public class Btn_OnClick : MonoBehaviour,IPointerClickHandler,IPointerDownHandler,IPointerUpHandler,IPointerExitHandler
{
    // 按压的持续时间
    public float pressDurationTime = 1;
    // 按压的响应次数
    public bool responseOnceByPress = false;
    // 双击的间隔时间
    public float doubleClickIntervalTime = 0.2f;
    // 拖动的间隔时间
    public float dragIntervalTime = 0.2f;
    // 拖动的鼠标间隔距离
    public float dragIntervalPos = 0.01f;

    public UnityEvent onDoubleClick;
    public UnityEvent onPress;
    public UnityEvent onClick;
    public UnityEvent onDrag;

    private bool isDown = false;
    private bool isPress = false;
    private bool isDrag = false;
    private float downTime = 0;

    private float clickIntervalTime = 0;
    private int clickTimes = 0;

    private Vector3 mousePosLast = Vector3.zero;//点击后的拖动位置

    Btn_OnClick btn;

    void Start()
    {
        btn = GetComponent<Btn_OnClick>();
        btn.onClick.AddListener(Click);
        btn.onPress.AddListener(Press);
        btn.onDoubleClick.AddListener(DoubleClick);
        btn.onDrag.AddListener(Drag);
    }

    void Click()
    {
        Debug.Log("单击");
    }

    void Press()
    {
        Debug.Log("按压");
    }

    void DoubleClick()
    {
        Debug.Log("双击");
    }

    void Drag()
    {
        Debug.Log("拖动");
    }

    void Update()
    {

        if (isDown)
        {
            if (responseOnceByPress && isPress)
            {
                return;
            }
            downTime += Time.deltaTime;
            isDrag = Vector3.Distance(Input.mousePosition, mousePosLast) > dragIntervalPos;
            if (downTime > pressDurationTime && !isDrag)
            {
                isPress = true;
                onPress.Invoke();
            }
            if (downTime > dragIntervalTime && isDrag)
            {
                onDrag.Invoke();
            }
        }
        if (clickTimes >= 1)
        {
            clickIntervalTime += Time.deltaTime;
            if (clickIntervalTime >= doubleClickIntervalTime)
            {
                if (clickTimes >= 2)
                {
                    onDoubleClick.Invoke();
                }
                else
                {
                    onClick.Invoke();
                }
                clickTimes = 0;
                clickIntervalTime = 0;
            }
        }
    }

    public void OnPointerClick(PointerEventData eventData)
    {
        if (!isPress)
            clickTimes += 1;
        else
            isPress = false;
    }

    public void OnPointerDown(PointerEventData eventData)
    {
        isDown = true;
        downTime = 0;
        mousePosLast = Input.mousePosition;
    }

    public void OnPointerExit(PointerEventData eventData)
    {
        isDown = false;
        isPress = false;
    }

    public void OnPointerUp(PointerEventData eventData)
    {
        isDown = false;
    }
}

👉4-2 效果如下

在这里插入图片描述
在这里插入图片描述

👉4-3 录屏

👉五、Model的鼠标点击事件

👉5-1. 第一步新建一个模型Cube

👉5-2. 第二步新建一个脚本挂在Cube上面

👉5-3. OnMouseEnter当鼠标进入碰撞器的时候触发

在这里插入图片描述
在这里插入图片描述

👉5-4. OnMouseExit当鼠标离开碰撞盒的时候触发

在这里插入图片描述
在这里插入图片描述

👉5-5. OnMouseUpAsButton当鼠标在碰撞器上按下并松开的时候触发

在这里插入图片描述
在这里插入图片描述

👉5-6. 实现如下

完整代码示例如下:

代码语言:javascript
复制
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 脚本挂到模型上,模型必须有碰撞盒
/// </summary>
public class Cube_OnClick : MonoBehaviour
{
    /// <summary>
    /// 当鼠标进入碰撞器的时候触发
    /// </summary>
    private void OnMouseEnter()
    {
        Debug.Log("进入了");
    }
    /// <summary>
    ///当鼠标离开碰撞盒的时候触发
    /// </summary>
    private void OnMouseExit()
    {
        Debug.Log("离开了");
    }
    /// <summary>
    /// 当鼠标在碰撞器上按下并松开的时候触发
    /// </summary>
    private void OnMouseUpAsButton()
    {
        Debug.Log("点击了模型");
    }
}

👉六、最终效果

UnityUI点击模型点击

补充: 注意事项

  1. 事件冲突处理 单击与双击冲突: 双击会先触发一次单击事件,需通过延迟执行单击逻辑(如协程)或标记位解决:
代码语言:javascript
复制
private IEnumerator ClickCheck() {
    yield return new WaitForSeconds(0.3f);
    if (!_isDoubleClick) {
        Debug.Log("单击触发");
    }
    _isDoubleClick = false;
}

拖动与点击冲突: 拖动操作可能误触发点击事件,可通过判断拖动距离阈值(eventData.delta)或拖动时间阈值区分。

  1. 性能优化 避免在 OnDrag 中频繁执行耗时操作(如实例化对象)。

使用对象池或缓存机制优化频繁的UI更新。

  1. 多平台适配 移动端触控灵敏度: 拖动阈值需适配不同设备DPI,可通过 EventSystem.current.pixelDragThreshold 动态调整。

输入兼容性: 同时支持鼠标和触摸输入时,需统一处理 PointerEventData.InputButton。

  1. UI层级与射线遮挡 事件穿透: 确保UI元素的 Raycast Target 属性正确设置,避免下层UI意外接收事件。

Canvas层级: 调整Canvas的 Sort Order 或使用 GraphicRaycaster 控制事件优先级。

  1. 坐标转换 拖动时需正确转换屏幕坐标到UI本地坐标,使用 RectTransformUtility.ScreenPointToLocalPointInRectangle。 确保UI的锚点(Anchor)和轴心(Pivot)设置合理,避免位置偏移。

总结 核心思路:通过Unity事件接口监听输入,结合时间、距离阈值和状态标记区分不同操作。

关键点:解决事件冲突、优化性能、多平台适配。

扩展方向:结合Unity的 Input System 实现更复杂的交互(如长按、滑动)。

👉总结

如果觉得本篇文章有用别忘了点个关注,关注不迷路,持续分享更多Unity干货文章。 你的点赞就是对博主的支持,有问题记得评论留言 本次总结的就是Unity3D实现UI的单击、双击、拖动状态判断, 有需要会继续增加功能 如能帮助到你,就帮忙点个赞吧,三连更好哦,谢谢 你的点赞就是对博主的支持,有问题记得留言评论哦! 不定时更新Unity开发技巧,觉得有用记得一键三连哦。么么哒!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-04-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 👉一、 前言
  • 👉二、鼠标的点击事件
    • 👉2-1 鼠标输入的API
  • 👉三、UI的点击事件
    • 👉3-1 UI点击事件API
      • 👉3-1-1 所引用的命名空间
    • 👉3-2 代码如下
  • 👉四、使用步骤
    • 👉4-1 实现UI的单价、双击、按压、拖动的不同状态判断
    • 👉4-2 效果如下
    • 👉4-3 录屏
  • 👉五、Model的鼠标点击事件
    • 👉5-1. 第一步新建一个模型Cube
    • 👉5-2. 第二步新建一个脚本挂在Cube上面
    • 👉5-3. OnMouseEnter当鼠标进入碰撞器的时候触发
    • 👉5-4. OnMouseExit当鼠标离开碰撞盒的时候触发
    • 👉5-5. OnMouseUpAsButton当鼠标在碰撞器上按下并松开的时候触发
    • 👉5-6. 实现如下
  • 👉六、最终效果
  • 👉总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档