unityevent与持续按键触发

上一篇中提到一种鼠标按下时的事件触发,即采用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 = 0;
    float posDragging = 0;

    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 = 0;

        if (posDragging - posStart > 0)
        {
            scale = 1;
        }
        else if(posDragging - posStart < 0)
        {
            scale = -1;
        }

        axisRotation.Rotate(Vector3.up * speedRatate * scale);
        posStart = posDragging;
        //Debug.Log("on Drag:" + eventData.position);
    }
}
复制代码

 

posted @   81192  阅读(6497)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示