unity3D 游戏物体同时绑定单击、双击事件

  前言

  在unity中我们常用的获取鼠标点击的方法有

  在3D场景中,一般用在Update方法中,每一帧调用

void Update(){
    if(Input.GetMouseButtonDown(0)){
        Debug.log("鼠标左键点击");
    }
}

  在画布场景中,一般用在OnGUI方法中,这个也是一个循环调用的方法

    void OnGUI()
    {
        Event e = Event.current;
        if (e.isMouse && (e.clickCount == 2))
        {
            Debug.Log("用户双击了鼠标");
        }
    }

  当我们想同时给一个游戏对象绑定单击、双击事件是就会一个问题,双击事件必然会触发至少一次单击事件,不管你点的有多快,因此我们需要引入定时器来解决这个问题

  定时器介绍

  简单介绍

using System;
using System.Collections;
using System.Runtime.CompilerServices;
using UnityEngine.Bindings;
using UnityEngine.Internal;
using UnityEngine.Scripting;

namespace UnityEngine
{
  //MonoBehaviour是每个Unity脚本派生的基类
  public class MonoBehaviour : Behaviour
  {
    //检查当前是否有定时器
    public bool IsInvoking()

    //取消所有定时器调用
    public void CancelInvoke()

    //在time秒后,调用方法名为methodName的方法
    public void Invoke(string methodName, float time)

    //在time秒后,调用方法名为methodName的方法,然后每repeatRate秒重复一次
    public void InvokeRepeating(string methodName, float time, float repeatRate)

    //取消方法名为methodName的定时器调用
    public void CancelInvoke(string methodName)

    //检查在方法名为methodName上是否有定时器调用
    public bool IsInvoking(string methodName)

    //其他的介绍省略...
  }
}

  MonoBehaviour是每个Unity脚本派生的基类,只要脚本引入了UnityEngine可以直接使用

  前面也有用System.Timers.Timer来实现,定时器也能正常触发,但有一个问题,在定时函数中,我无法访问gameObject,但是可以访问到我们的两个标识,很奇怪,如果有在函数中调用到gameObject等其他属性,程序也不打印报错信息,脚本直接终止,再点击对象已经没有反应,后面通过断点发现,访问这些属性将会产生一个异常:Exception of type System.NotSupportedException,因此放弃使用这个定时器

  思路

  1、当触发点击,且点击对象为当前绑定脚本的对象才继续往下执行

  2、将单、双击标识设置取反,当前为false

  3、判断是否为新一轮

  4、触发定时器,在300毫秒后执行定时调用函数,同时锁定本次判断,再本次判断没结束之前不会触发定时器

  5、在函数里进行单、双击的判断(false单击、true双击),同时重置标识,开启下一轮

  那么在这300毫秒的时间里,如果我们再次点击将会执行到第二步,单、双击标识将会被设置成true,则定时调用函数的if分支就会走双击

  bug

  那么问题来了,如果有人手速非常快,他在300毫秒内点了好几下那岂不是会有问题?如果他点了两下,那定时调用函数的if分支又会走单击....

  这种情况下只能设置一个合适的触发时间来解决了

  最终脚本、效果

using UnityEngine;

/**
 * 鼠标点击事件绑定
 */
public class Click : MonoBehaviour
{
    private Ray _ray;//物理射线相关

    public RaycastHit _hit;//物理射线相关

    private bool _first = true;//新一轮标识(或者也可以叫是否结束的标识)

    private bool _flag = true;//单击或双击的标识(默认单击)

    private void Update()
    {
        monitor();
    }

    /**
     * 鼠标单、双击监听
     */
    private void monitor()
    {
        //触发鼠标左键点击
        if (!Input.GetMouseButtonDown(0)) return;

        //射线检测到的对象是当前对象
        if (Camera.main != null) _ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (!Physics.Raycast(_ray, out _hit) || _hit.collider.gameObject != gameObject) return;

        _flag = !_flag;

        //上一次的事件是否已经执行完毕,也就是判断是否为新一轮
        if (!_first) return;

        _first = false;

        //初始化定时器,300毫秒后执行预定方法
        Invoke("Timer", 0.3f);
    }

    /**
     * 定时调用函数
     */
    private void Timer()
    {
        //进行判断
        if (_flag)
        {
            OnDblclick();
        }
        else
        {
            OnClick();
        }

        //定时调用结束,重置标识
        _first = true;
        _flag = true;
    }

    /**
     * 单击事件
     */
    private void OnClick()
    {
        Debug.Log(gameObject.name + "单击事件被触发");
    }

    /**
     * 双击事件
     */
    private void OnDblclick()
    {
        Debug.Log(gameObject.name + "双击事件被触发");
    }
}

  上图的鼠标操作流程:单击,双击,单击,双击,双击,单击;(具体打印情况看控制台右边的打印次数)

  后记

  unity3D 游戏物体同时绑定单击、双击事件暂时记录到这,后续还可以进一步封装,使游戏对象绑定单、双击更加简单

原文地址:https://www.cnblogs.com/huanzi-qch/p/12012721.html

时间: 2024-10-14 06:50:45

unity3D 游戏物体同时绑定单击、双击事件的相关文章

KendoUI Grid 绑定单击双击事件

原文:http://blog.csdn.net/sakuya_tan/article/details/51437857 <div id="grid"></div> <script> var grid = $("#grid").kendoGrid({ columns: [ { field: "id" }, { field: "name" } ], dataSource: [ { id: &qu

JS同时绑定单双击事件

这两天工作上遇到这种情况,需要在tree组件上的每个节点绑定单双击事件,怎么实现呢?借助js的定时器来实现这个功能吧,思路是这样的:给定时器设置一个时间,如果在该时间段内用户点击一次则触发单机事件,大于1的话就执行双击事件.废话不多说,这里我们用一个示例来说明: 首先要引入jQuery,这里用jquery来为测试元素绑定事件 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <

jsp页面单击 双击事件区分

点击事件的执行顺序: 单击(click):mousedown,mouseout,click: 双击(dblclick):mousedown,mouseout,click , mousedown,mouseout,click,dblclick: 在双击事件(dblclick),触发的两次单击事件(click)中,第一次的单击事件(click)会被屏蔽掉,但第二次不会.也就是说双击事件(dblclick)会返回一次单击事件(click)结果和一次双击事件(dblclick) 结果.而不是一次双击事件

EXT gird添加单击 双击事件

1.双击 var dblGrid = new Ext.grid.GridPanel({           }   dblGrid.addListener('rowdblclick', rowdblclickFn); function rowdblclickFn(grid, rowindex, e){          grid.getSelectionModel().each(function(rec){          alert(rec.get(fieldName)); //fieldN

转载:Easyui中的Grid的行单击双击事件

$('#surveryGird').datagrid( {  loadMsg : "正在加载数据",  url : url,  height : 320,  width : 270,  searching : true,  pagination : true,//分页  sortName: 'reportTimeStr',  sortOrder: 'desc',  remoteSort: false,  onClickRow:function(rowIndex,rowData){   

GRIDVIEW单击双击事件

protected void gvTeacherTaskList_RowCommand(object sender, GridViewCommandEventArgs e) { if (e.CommandName == "ShowDetail") { } } protected void gvTeacherTaskList_DataBound(object sender, EventArgs e) { foreach (GridViewRow row in gvTeacherTaskL

[转] Ext Grid (ExtJs)上的单击以及双击事件

例1: 1.双击 var cb = new Ext.grid.RowSelectionModel({ singleSelect:true //如果值是false,表明可以选择多行:否则只能选择一行 }); var alarmGrid = new Ext.grid.GridPanel({ } alarmGrid.addListener('rowdblclick', rowdblclickFn); function rowdblclickFn(grid, rowindex, e){ grid.get

IE和Chrome执行javascript对鼠标双击事件的不同响应

最近在用天地图API帮同学做点开发的工作,主要是基于天地图的API实现违法用地举报的在线地图标绘,要实现的效果如下: 由于是基于天地图API的TPolygonTool工具实现面积量测和多边形绘制功能,实现思路如下: (1)基于按钮的鼠标点击事件开启多边形标绘工具: 1 //开启/关闭违法标绘工具 2 function onClickPolyTool() { 3 var btn = document.getElementById("polyToolBtn"); 4 if (btn.val

jquery 单击和双击事件冲突解决方案

本人需要给bootstrap-treeview的树节点添加双击事件.而该插件原生方法中不带双击事件功能.该插件的节点默认绑定的单击事件,由此引起了单击事件和双击事件的冲突. 编写测试代码 引起冲突的代码: 问题效果展示: 每一次触发双击事件都会引起两次单击事件 解决冲突的代码: 解决问题效果展示: 完美解决单击事件和双击事件冲突问题 这里主要用到两个HTML DOM Window对象中函数,settimeout(),clearTimeout() 我这里两个单击事件触发的时间间隔设置在等于300毫