Skip to content

以前做项目,模仿NGUI的事件监听,写了个脚本,具体如下,实现了单击、双击、按压、长按等事件

c#
using UnityEngine;
using UnityEngine.EventSystems;
using System.Collections;

public class TTEventTrigger : EventTrigger
{
    public delegate void VoidEventDataBase(BaseEventData eventData);
    public delegate void VoidEventDataPointer(PointerEventData eventData);

    public VoidEventDataPointer onClick;
    public VoidEventDataPointer onDoubleClick;
    public VoidEventDataPointer onDown;
    public VoidEventDataPointer onEnter;
    public VoidEventDataPointer onExit;
    public VoidEventDataPointer onUp;
    public VoidEventDataBase onSelect;
    public VoidEventDataBase onUpdateSelect;
    public VoidEventDataPointer onBeginDrag;
    public VoidEventDataPointer onDrag;
    public VoidEventDataPointer onEndDrag;
    public VoidEventDataPointer onDrop;
    public VoidEventDataPointer onScroll;
    public VoidEventDataPointer onLongPress;
    public VoidEventDataPointer onPress;

    public static TTEventTrigger Get(GameObject go)
    {
        TTEventTrigger listener = go.GetComponent<TTEventTrigger>();
        if (listener == null) listener = go.AddComponent<TTEventTrigger>();
        return listener;
    }

    private int clickCount;
    private float clickTime;
    private bool isDrag;

    public override void OnPointerClick(PointerEventData eventData)
    {
        if (onDoubleClick != null) StartDoubleClick();
        if (onClick == null) return;
        if (isDrag && (onDrag != null || onPress != null || onLongPress != null)) return;
        onClick(eventData);
    }

    private PointerEventData tempData;
    public override void OnPointerDown(PointerEventData eventData)
    {
        tempData = eventData;
        if (onLongPress != null) StartCoroutine(nameof(IELongPress));
        if (onPress != null) StartCoroutine(nameof(IEPress));
        if (onDown != null) onDown(eventData);
        isDrag = false;
    }
    public override void OnPointerEnter(PointerEventData eventData)
    {
        if (onEnter != null) onEnter(eventData);
    }
    public override void OnPointerExit(PointerEventData eventData)
    {
        if (onExit != null) onExit(eventData);
    }
    public override void OnPointerUp(PointerEventData eventData)
    {
        if (onLongPress != null) StopCoroutine(nameof(IELongPress));
        if (onPress != null) StopCoroutine(nameof(IEPress));
        onUp?.Invoke(eventData);
        //isDrag = false; up事件比click先响应
    }
    public override void OnSelect(BaseEventData eventData)
    {
        onSelect?.Invoke(eventData);
    }
    public override void OnUpdateSelected(BaseEventData eventData)
    {
        onUpdateSelect?.Invoke(eventData);
    }
    public override void OnBeginDrag(PointerEventData eventData)
    {
        onBeginDrag?.Invoke(eventData);
    }
    public override void OnDrag(PointerEventData eventData)
    {
        isDrag = true;
        onDrag?.Invoke(eventData);
    }
    public override void OnEndDrag(PointerEventData eventData)
    {
        onEndDrag?.Invoke(eventData);
    }

    public override void OnDrop(PointerEventData eventData)
    {
        //isDrog = true;
        onDrop?.Invoke(eventData);
    }

    private IEnumerator IELongPress()
    {
        bool isPress = false;
        float timePressStarted = Time.time;
        while (true)
        {
            if (isPress)
            {
                onLongPress(tempData);
            }
            else if (Time.time - timePressStarted > 0.2f)
            {
                isDrag = true;
                isPress = true;
                onLongPress(tempData);
                //isPress = false;
            }
            yield return null;
        }
    }
    private IEnumerator IEPress()
    {
        bool isPress = true;
        float timePressStarted = Time.time;
        while (isPress)
        {
            if (Time.time - timePressStarted > 0.25f)
            {
                isDrag = true;
                onPress(tempData);
                isPress = false;
            }
            yield return null;
        }
    }
    private void StartDoubleClick()
    {
        clickCount++;
        if (Time.time - clickTime < 0.3f)
        {
            if (clickCount > 1)// && onDoubleClick != null)
            {
                onDoubleClick(tempData);
                clickCount = 0;
            }
            else { clickCount = 1; }
            clickTime = Time.time;
        }
        else
        {
            clickCount = 1;
            clickTime = Time.time;
        }
    }

    void Start()
    {
        UnityEngine.UI.Graphic gi = GetComponent<UnityEngine.UI.Graphic>();
        if (gi != null)
        {
            gi.raycastTarget = true;
        }
    }
}
粤ICP备19088787号-1