Unity3D UGUI Button同时监听点击事件和长按事件

有些游戏都会有这样一个需求,比如一个按钮点击可以进行攻击,长按又可以释放技能的需求。

我们做一个类似Button的组件,只需要挂载到相应的按钮上面,即可像Button一样注册长按事件。

1.我们新建一个脚本RepeatButton,继承接口IPointerDownHandler, IPointerUpHandler, IPointerExitHandler,获取相应的按下,抬起,结束等事件。

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

public class RepeatButton : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerExitHandler
{
    public Vector2 position;
    public bool interactable = true;

    public bool invokeOnce = false;//是否只调用一次  
    private bool hadInvoke = false;//是否已经调用过  

    public float interval = 0.1f;//按下后超过这个时间则认定为"长按"  
    private bool isPointerDown = false;
    private float recordTime;

    public UnityEvent onClickDown = new UnityEvent();//按下时调用  
    public UnityEvent onPress = new UnityEvent();//按住时调用  
    public UnityEvent onRelease = new UnityEvent();//松开时调用 

    void Start()
    {

    }

    void OnDisable() {
        isPointerDown = false;
    }

    void Update()
    {
        if ((invokeOnce && hadInvoke) || interactable == false) return;
        if (isPointerDown)
        {
            if ((Time.time - recordTime) > interval)
            {
                onPress.Invoke();
                hadInvoke = true;
            }
        }
    }

    public void OnPointerDown(PointerEventData eventData)
    {
        isPointerDown = true;
        recordTime = Time.time;
        position = eventData.position;
        onClickDown.Invoke();
    }

    public void OnPointerUp(PointerEventData eventData)
    {
        isPointerDown = false;
        hadInvoke = false;
        position = eventData.position;
        onRelease.Invoke();
    }

    public void OnPointerExit(PointerEventData eventData)
    {
        isPointerDown = false;
        hadInvoke = false;
        position = eventData.position;
        //onRelease.Invoke();
    }
    public void RemoveAddListener()
    {
        onClickDown.RemoveAllListeners();
        onPress.RemoveAllListeners();
        onRelease.RemoveAllListeners();
    }
}


2.然后我们在逻辑脚本上添加代码。

    Button Btn;
    bool isPress = false;

    void Start () {
        Btn.onClick.AddListener(ClickBtn);
        Btn.GetComponent().onPress.AddListener(LongPress);
    }

    void OnDestroy()
    {
        Btn.onClick.RemoveListener(ClickBtn);
        Btn.GetComponent().onPress.RemoveListener(LongPress);
    }

    /// 
    /// 点击
    /// 
    private void ClickBtn()
    {
        if (isPress)
        {
            isPress = false;
            return;
        }
        //TODO 点击逻辑

    }

    /// 
    /// 长按
    /// 
    private void LongPress()
    {
        isPress = true;
        //TODO 长按逻辑
    }

我这里为什么没有注册长按抬起的事件?这是因为长按抬起之后会执行onClick点击事件,在抬起之后设置isPress=false并不能过滤到点击事件,所以我直接在点击事件里面判断isPress = true时就return了。

你可能感兴趣的:(UGUI)