上一篇中提到一种鼠标按下时的事件触发,即采用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. Python人工智能第一篇:语音合成和语音识别

    Python人工智能第一篇:语音合成和语音识别 ​ 此篇是人工智能应用的重点,只用现成的技术不做底层算法,也是让初级程序员快速进入人工智能行业的捷径.目前市面上主流的AI技术提供公司有很多,比如百度, ...

  2. 【JVM 知识体系框架总结】

    JVM 内存分布 线程共享数据区: 方法区->类信息,静态变量 堆->数组对象 线程隔离区 虚拟机栈-> 方法 本地方法栈->本地方法库 native 堆.程序计数器 JVM ...

  3. 『TensorFlow2.0正式版教程』极简安装TF2.0正式版(CPU&GPU)教程

    0 前言 TensorFlow 2.0,今天凌晨,正式放出了2.0版本. 不少网友表示,TensorFlow 2.0比PyTorch更好用,已经准备全面转向这个新升级的深度学习框架了. ​ 本篇文章就 ...

  4. poj-2232 New Stone-Forfex-Cloth Game 思维题

    Acm is a clever boy, and he developed a new game form the old Stone-Forfex-Cloth game. In this game, ...

  5. layDate——设置最大日期不能超过当前日期

    例如,当前年份是2018年,实现效果如下,2018年之后年份不可操作: 具体代码实现: layui.use([ 'laydate'], function () { var laydate = layu ...

  6. jenkins+svn+Ant+tomcat+非maven项目构建

    首先,输入项目名称,创建一个自由风格的项目; 然后,配置旧项目的策略参数,目的是防止构建项目太多,占用资源. 下一步,jdk版本选择: 下一步,关联svn项目. 下一步:配置ant 看不清,再来一张. ...

  7. java后端研发经典面试题总结

    垃圾回收算法 1.标记-清除算法 标记-清除算法是最基本的算法,和他的名字一样,分为两个步骤,一个步骤是标记需要回收的对象.在标记完成后统一回收被标记的对象.这个算法两个问题.一个是效率问题,标记和清 ...

  8. 夯实Java基础系列15:Java注解简介和最佳实践

    Java注解简介 注解如同标签 Java 注解概述 什么是注解? 注解的用处 注解的原理 元注解 JDK里的注解 注解处理器实战 不同类型的注解 类注解 方法注解 参数注解 变量注解 Java注解相关 ...

  9. Vue.js实战学习笔记(中)

    1.递归组件给组件设置name属性,组件就可以在它的模板内调用自己,但必须给一个条件来限制递归数量.<div id="app"> <child-component ...

  10. Scala 学习笔记之集合(6)

    object CollectionDemo7 { def main(args: Array[String]): Unit = { //数组使用 val arr = Array("red&qu ...