[Unity] 交互之双击

本文档介绍了如何在Unity中,通过检测鼠标左键双击事件,结合Raycasting实现对屏幕点击位置的物体进行销毁。通过`GetMouseButtonDown`检查鼠标按下,`Physics.Raycast`进行碰撞检测,配合`TouchPhase`判断是否为双击操作,进而控制`Destroy`函数删除相应的游戏对象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NewBehaviourScript : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButtonDown(0))//0 1 2 分别代表鼠标的左右和中间按键
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); // 主相机屏幕点转换为朝向鼠标点击处的射线
            RaycastHit hitinfo;//用来接受射线的信息
            if (Physics.Raycast(ray,out hitinfo))//射线碰到了物体
            {
                if (Input.touchCount == 1 && Input.GetTouch(0).phase == TouchPhase.Began)
                {//触摸次数为1,一个触摸点,手指刚触摸到屏幕的时候
                    if (Input.GetTouch(0).tapCount==2)//在触摸点0处的敲击次数=2,意味着双击
                    Destroy(hitinfo.collider.gameObject);//双击摧毁事物
                }
            }
        }
    }
}

直接在update里面写就行, // Update is called once per frame,每一帧调用一次

        //
        // 摘要:
        //     Returns true during the frame the user pressed the given mouse button.
        //
        // 参数:
        //   button:
        [NativeThrows]
        public static bool GetMouseButtonDown(int button);

在用户释放鼠标按钮并再次按下它之前,它不会返回 true。 按钮值为 0 表示主按钮(通常是左按钮),1 表示辅助按钮,2 表示中间按钮。

Physics.Raycast(ray,out hitinfo)
在这里插入图片描述

			//ray	光线的起点和方向。
            //hitInfo	如果返回 true,则 hitInfo 将包含有关最近的碰撞体的命中位置的更多信息。
            //bool 当光线与任何碰撞体相交时,返回 true,否则返回 false。

touchCount为触摸次数,也意味着不同的触摸对象

        //
        // 摘要:
        //     Number of touches. Guaranteed not to change throughout the frame. (Read Only)
        public static int touchCount { get; }

GetTouch(0).phase,获得第一个触摸点的状态

index的真正作用,获取触摸到屏幕的第几个点。要知道同一时刻可能有多个点在被触碰,所以如果当前你只有一个手指在按屏幕,那当然就只有(0)了,如果有两个,那0是一个点,1是一个点。以此类推。
gettouch()并不代表你当前时刻一定有手指在触摸屏幕,它只是从touches列表里获取,如果列表为空,自然报错了。而那个touches列表在哪呢?Input.touches,是有这个方法的,所以其实gettouch(0)和Touch[] touches = Input.touches; touches[0] 的效果是一样的。

在这里插入图片描述

hitinfo.collider
射线撞击,因此撞击的物体也要添加collider组件

### Unity 中实现鼠标双击判断逻辑 在 Unity 中,可以通过多种方式实现鼠标双击的判断逻辑。以下是几种常见的方法及其详细说明。 --- #### 方法一:基于时间间隔的双击检测 这种方法的核心思想是记录两次鼠标点击之间的时间差,并将其与预设的阈值进行比较。如果时间差小于阈值,则判定为双击。 ##### 关键代码示例 ```csharp using UnityEngine; public class MouseDoubleClick : MonoBehaviour { private float doubleClickThreshold = 0.3f; // 双击时间间隔阈值 private float lastClickTime = 0f; // 上次点击的时间戳 void Update() { if (Input.GetMouseButtonDown(0)) // 检测鼠标左键按下 { float currentTime = Time.time; // 获取当前时间 if (currentTime - lastClickTime < doubleClickThreshold) // 判断时间差是否满足条件 { OnDoubleClick(); // 触发双击事件 } lastClickTime = currentTime; // 更新上次点击时间 } } void OnDoubleClick() { Debug.Log("Detected Double Click!"); } } ``` ##### 解析 - 使用 `Input.GetMouseButtonDown(0)` 来捕获鼠标的左键点击事件。 - 记录每次点击的时间戳并通过计算时间差来判断是否构成双击[^1]。 - 这种方法简单高效,适用于大多数场景下的双击检测需求。 --- #### 方法二:利用 `OnGUI` 和 `Event.current.clickCount` Unity 提供了内置属性 `Event.current.clickCount`,可以直接获取当前点击的次数(单击或双击)。不过需要注意的是,这种方式仅限于编辑器环境中的 GUI 系统,不推荐用于现代 UI 或运行时逻辑。 ##### 关键代码示例 ```csharp void OnGUI() { Event e = Event.current; if (e.isMouse && e.type == EventType.MouseDown && e.clickCount == 2) { Debug.Log("Double Click Detected via OnGUI!"); // 输出日志 } } ``` ##### 解析 - 此方法依赖于 `OnGUI` 函数和 `Event.current.clickCount` 属性[^2]。 - 尽管简洁明了,但由于其局限性(无法兼容 UGUI),一般较少使用。 --- #### 方法三:针对特定对象的双击检测 当需要检测用户是否双击某个特定的游戏对象时,可以结合射线投射技术以及时间间隔算法完成。 ##### 关键代码示例 ```csharp using UnityEngine; public class ObjectDoubleClick : MonoBehaviour { public Camera mainCamera; // 主摄像机引用 private float doubleClickThreshold = 0.3f; // 双击时间间隔阈值 private float lastClickTime = 0f; // 上次点击的时间戳 void Update() { if (Input.GetMouseButtonDown(0)) // 检测鼠标左键按下 { Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition); RaycastHit hit; if (Physics.Raycast(ray, out hit)) // 检查是否有碰撞体被命中 { GameObject clickedObject = hit.collider.gameObject; if (clickedObject.CompareTag("Clickable")) // 假设目标对象带有 "Clickable" 标签 { float currentTime = Time.time; // 获取当前时间 if (currentTime - lastClickTime < doubleClickThreshold) // 判断时间差是否满足条件 { OnDoubleClick(clickedObject); // 触发双击事件 } lastClickTime = currentTime; // 更新上次点击时间 } } } } void OnDoubleClick(GameObject obj) { Debug.Log($"Double Clicked on {obj.name}!"); } } ``` ##### 解析 - 结合射线投射技术和标签过滤机制,确保只有符合条件的对象才能触发双击事件。 - 更加灵活地适应复杂场景下的交互需求[^3]。 --- #### 方法四:UGUI 下的双击检测 对于基于 Unity 新版 UI(UGUI)的应用程序,可以借助接口 `IPointerClickHandler` 实现精确的双击检测。 ##### 关键代码示例 ```csharp using UnityEngine; using UnityEngine.EventSystems; public class UIDoubleClick : MonoBehaviour, IPointerClickHandler { public float doubleClickThreshold = 0.2f; // 双击时间间隔阈值 private float lastClickTime = 0f; // 上次点击的时间戳 public void OnPointerClick(PointerEventData eventData) { float currentTime = Time.time; // 获取当前时间 if (currentTime - lastClickTime < doubleClickThreshold) // 判断时间差是否满足条件 { OnDoubleClick(eventData); // 触发双击事件 } lastClickTime = currentTime; // 更新上次点击时间 } void OnDoubleClick(PointerEventData eventData) { Debug.Log("UI Element Double Clicked!"); } } ``` ##### 解析 - 继承自 `IPointerClickHandler` 接口,使得脚本能响应指针点击事件。 - 特别适合处理 UGUI 元素上的双击交互[^4]。 --- ### 总结 以上四种方法分别适用于不同的应用场景: - **方法一** 是最通用的方式,适配绝大多数基础需求; - **方法二** 虽然简便但受限于旧版 GUI 系统; - **方法三** 面向三维空间内的精准对象检测; - **方法四** 则专注于现代化 UGUI 的交互设计。 开发者应根据具体项目需求选择合适的解决方案。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值