上一篇中提到一种鼠标按下时的事件触发,即采用eventtrigger设定pointerdown和pointerup并绑定相应事件。但是若要实现持续按键则需要对绑定的每个方法都添加实现持续按键方法。所以在此通过unityevent来简化过程。

(一)unityevent

unityevent为unity自定义的unity事件,需要与委托unityaction(它需要添加到event的监听中使用)。

以下为例:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events; public class UniytEventTest : MonoBehaviour { UnityAction action;
[SerializeField]
UnityEvent actionEvent = new UnityEvent(); public void OnTest01()
{
print("test01");
}
public void OnTest02()
{
print("test02");
}
// Use this for initialization
void Start () {
action = new UnityAction(OnTest01);
action += OnTest02; if (action != null)
{
actionEvent.AddListener(action);
}
actionEvent.Invoke();
} // Update is called once per frame
void Update () { }
}

首先unityevent的特性声明

 [SerializeField]

表示此事件会出现在unity中的面板上,可以绑定事件,否则不可以。定义好事件以后就可以通过invoke方法激活一次。在此多说明一点,若通过代码绑定方法,unityaction默认为无参数的,若果需要带参数则需要通过泛型unityaction<T>来实现

(二)持续按键

通过unityEvent来实现持续按键,按键时事件触发时间间隔为0.1s

代码如下:

using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using System.Collections;
using UnityEngine.UI; public class ConstantPressEvent : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerExitHandler
{
public float interval = 0.1f; [SerializeField]
UnityEvent m_OnLongpress = new UnityEvent(); private bool isPointDown = false;
private float invokeTime; // Use this for initialization
void Start()
{
} // Update is called once per frame
void Update()
{
if (isPointDown)
{
if (Time.time - invokeTime > interval)
{
//触发点击;
m_OnLongpress.Invoke();
invokeTime = Time.time;
}
}
} public void OnPointerDown(PointerEventData eventData)
{
m_OnLongpress.Invoke(); isPointDown = true; invokeTime = Time.time;
} public void OnPointerUp(PointerEventData eventData)
{
isPointDown = false;
} public void OnPointerExit(PointerEventData eventData)
{
isPointDown = false;
}
}

(三)单击/长按组合

如果需要用到此按钮既有点击又有长按则可用如下代码

using System;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;

public class LongPressEvent : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerExitHandler
{
public float interval = 1f;

[SerializeField]
UnityEvent longPressEvent = new UnityEvent();

[SerializeField]
UnityEvent pressEvent = new UnityEvent();

private bool isPointDown = false;
private float invokeTime = 0;
private bool longPressInvoked = false;
private bool isPointUp = false;
private bool isDragging = true;

private float distance = 0;
private float precise = 5f;
private float time = 0.15f;
private Vector2 startPos;
private Vector2 endPos;

// Update is called once per frame
void Update()
{
if (isPointDown)
{
if (Time.time - invokeTime > interval)
{
//if (!isInvoked)
//{
// longPressEvent.Invoke();
// invokeTime = Time.time;
// isInvoked = true;
//}
longPressEvent.Invoke();
invokeTime = Time.time;
longPressInvoked = true;
}
}

if (isPointUp)
{
if (Vector2.Distance(startPos, endPos) <= precise && Time.time - invokeTime < time)//Vector2.Distance(startPos,endPos)<=precise&&
{
if (!longPressInvoked)
pressEvent.Invoke();
}

isPointUp = false;
longPressInvoked = false;
}
}

public void OnPointerDown(PointerEventData eventData)
{
startPos = eventData.position;
endPos = eventData.position;

isPointDown = true;
invokeTime = Time.time;
}

public void OnPointerUp(PointerEventData eventData)
{
endPos = eventData.position;
isPointUp = true;

isPointDown = false;
}

public void OnPointerExit(PointerEventData eventData)
{
endPos = eventData.position;
isPointDown = false;
longPressInvoked = false;
}
}

(四)滑动屏幕,旋转模型

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems; public class ModelRotation : MonoBehaviour, IDragHandler, IBeginDragHandler
{
public Transform axisRotation;//旋转对象
public float speedRatate = 0.1f; float posStart = ;
float posDragging = ; public void OnBeginDrag(PointerEventData eventData)
{
posStart = eventData.position.x;
posDragging = eventData.position.x;
//Debug.Log("begin Drag:"+eventData.position);
} public void OnDrag(PointerEventData eventData)
{
posDragging = eventData.position.x;
float scale = ; if (posDragging - posStart > )
{
scale = ;
}
else if(posDragging - posStart < )
{
scale = -;
} axisRotation.Rotate(Vector3.up * speedRatate * scale);
posStart = posDragging;
//Debug.Log("on Drag:" + eventData.position);
}
}

unityevent与持续按键触发的更多相关文章

  1. stm32F042 (二) 按键触发中断

    已经实现GPIO口输出高低电平控制LED,这里实现按键触发中断来改变LED闪亮的频率,因为PB3连着LED,所以PB3的输出模式没有改变,随意选一个GPIO口PA7接按键产生中断.因为nucleo开发 ...

  2. Python窗口学习之浅尝按键触发事件

    一.窗口上敲键盘触发事件(以Enter键为例) 二.点击窗口按钮触发事件(以鼠标左键双击为例) 代码: import tkinter as tk root = tk.Tk() root.geometr ...

  3. 纯C语言写的按键驱动,将按键逻辑与按键处理事件分离~

    button drive 杰杰自己写的一个按键驱动,支持单双击.连按.长按:采用回调处理按键事件(自定义消抖时间),使用只需3步,创建按键,按键事件与回调处理函数链接映射,周期检查按键. 源码地址:h ...

  4. 入门级的按键驱动——按键驱动笔记之poll机制-异步通知-同步互斥阻塞-定时器防抖

    文章对应视频的第12课,第5.6.7.8节. 在这之前还有查询方式的驱动编写,中断方式的驱动编写,这篇文章中暂时没有这些类容.但这篇文章是以这些为基础写的,前面的内容有空补上. 按键驱动——按下按键, ...

  5. JS触发事件大全

          事件 浏览器支持 解说 一般事件 onclick IE3.N2 鼠标点击时触发此事件 ondblclick IE4.N4 鼠标双击时触发此事件 onmousedown IE4.N4 按下鼠 ...

  6. emWin(ucGui) MULTIEDIT控件的按键响应处理 worldsing

    目前没有读过ucgui的源代码,通过应用代码测试出在FRAMEWIN的控件焦点顺序是样的: 按资源列表里创建的控件,默认将焦点落在第一个可接收焦点的控件,目前知道不可接收 焦点的控件有TEXT,在FR ...

  7. 游戏Demo(持续更新中...)

    格斗游戏 主要用于联系Unity的动画系统,并加入了通过检测按键触发不同的技能. WASD控制方向,AD为技能1,SW为技能2,右键跳跃,连续单机普通连招. 本来是要用遮罩实现跑动过程中的攻击动作,但 ...

  8. JS基础知识:Javascript事件触发列表

    Javascript是一种由Netscape的LiveScript发展而来的原型化继承的基于对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言. JavaScript使我们有能 ...

  9. 用LED灯和按键来模拟工业自动化设备的运动控制

    开场白: 前面三节讲了独立按键控制跑马灯的各种状态,这一节我们要做一个机械手控制程序,这个机械手可以左右移动,最左边有一个开关感应器,最右边也有一个开关感应器.它也可以上下移动,最下面有一个开关感应器 ...

随机推荐

  1. Exceptionless 5.0.0 本地Docker快速部署介绍

    在之前我有专门写两篇文章介绍过Exceptionless这款开源日志项目的使用和部署,但是当时是基于4.1.0版本(2017年的release),时隔两年多Exceptionless也推出了5.0.0 ...

  2. spring bean的生命周期与springmvc的生命周期

    配置在Spring中的Bean在Spring容器中从加载到销毁会经历那些过程呢?如果实现一些特定的Spring接口,这些特定接口的方法会在什么时候被调用呢?本文简单介绍一下这些过程. Bean在Spr ...

  3. ES6学习总结之Set和Map数据结构的理解

    前言 当我们需要存储一些数据的时候,首先想到的是定义一个变量用来存储,之后我们可能学了数组,发现数组比变量可以存储更多的数据,接着可能有其它的存储数据的方法等等,然而我今天需要介绍的是在ES6中比较常 ...

  4. 【产品】PM常用的流程图

    一.流程图分类 UML有很多种,大体可以分类两类:行为型的图和结构型的图.平时工作中的流程图,只要能把事情清晰的表明,用何种流程图表现形式,其实都无所谓. 但是,作为一名产品经理,共有哪些种类的流程图 ...

  5. ShaderHelper2 组件升级,支持自动枚举参数!

    ShaderHelper2 组件新体验视频演示: https://www.bilibili.com/video/av69314195/ ShaderHelper2 组件我们已经介绍过两次了,不了解的伙 ...

  6. vue-hash-calendar,移动端日期时间选择插件

    按照惯例,先上效果图 vue-hash-calendar 基于 vue 2.X 开发的日历组件 支持手势滑动操作·1 原生 js 开发,没引入第三方库 上下滑动 切换 周/月 模式 [周模式中] 左右 ...

  7. httprouter框架 (Gin使用的路由框架)

    之前在Gin中已经说到, Gin比Martini的效率高好多耶, 究其原因是因为使用了httprouter这个路由框架, httprouter的git地址是: httprouter源码. 今天稍微看了 ...

  8. JPG和PNG特性分析及适用范围

    个人博客: http://mcchen.club JPG的特性   ----有损压缩 1.支持摄影图像或写实图像的高级压缩,并且可利用压缩比例控制图像文件大小. 2.有损压缩会使图像数据质量下降,并且 ...

  9. C# 8 - Range 和 Index(范围和索引)

    C# 7 的 Span C# 7 里面出现了Span这个数据类型,它可以表示另一个数据结构里连续相邻的一串数据,并且它是内存安全的. 例子: 这个图的输出是3,4,5,6. C# 8 的Range类型 ...

  10. 网络游戏开发-客户端2(自定义websocket协议格式)

    Egret官方提供了一个Websocket的库,可以让我们方便的和服务器长连接交互. 标题写的时候自定义websocket的协议格式.解释一下,不是说我们去动websocket本身的东西,我们是在we ...