unity3D技术分享

使用EventTrigger实现UGUI Button长按效果

2019-04-14  本文已影响0人  无糖Kel

版权说明:本文为博主原创文章,转载需注明出处

环境 Unity 2018.3.12f1


  Button的长按事件是开发中比较常用的一个事件,但是Unity并没有为我们提供长按回调,所以需要我们自己实现。网上大部分文章是通过实现IPointerDownHandlerIPointerUpHandler接口来实现的,这里我们通过注册EventTrigger事件来实现。

  首先先来写个扩展方法向Button对象注册EventTrigger事件.

public static void AddEventTrigger(this GameObject obj, EventTriggerType eventTriggerType,
    UnityAction<BaseEventData> action, bool isRemoveAllListeners, bool isClearTriggers)
{
    EventTrigger trigger = obj.GetComponent<EventTrigger>() ?? obj.AddComponent<EventTrigger>();

    if (trigger.triggers.Count == 0) trigger.triggers = new List<EventTrigger.Entry>();

    if (isRemoveAllListeners) trigger.triggers.Clear();

    if (isClearTriggers) trigger.triggers.RemoveAll((e) => e.eventID == eventTriggerType);

    EventTrigger.Entry entry = new EventTrigger.Entry() {eventID = eventTriggerType};

    entry.callback.AddListener(action);

    trigger.triggers.Add(entry);
}

  然后就需要注册事件了。这里我们模拟一下,通过两个按键来修改同一个值。


举例.png

实现原理:
  每次按下按键时开辟一个协程,根据需求设定长按时触发事件的频率。为避免协程进入死循环,需要判断按键是否处于按下状态,同时为避免在两次事件间隔中玩家重新按键导致同时开辟并运行多条协程的情况,需要获取协程唯一标识,将过时的协程释放掉。

  代码:

void Start()
{
    // 输出
    int num = 0;

    bool isPress;  // 标识是否处于按下状态
    long guid;  // 协程标识   这里使用DateTime.Now.Ticks来标识

    IEnumerator Press(bool add)
    {
        long ticks = DateTime.Now.Ticks;
        guid = ticks;

        Action(add);

        yield return new WaitForSeconds(1f); 

        while (isPress && guid == ticks) 
        {
            Action(add);

            yield return new WaitForSeconds(0.05f);
        }
    }

    void Action(bool add)
    {
        text.text = $"{(add ? ++num : --num)}";
    }

    //  注册PointerDown事件
    addBtn.AddEventTrigger(EventTriggerType.PointerDown, _ =>
    {
        isPress = true;
        StartCoroutine(Press(true));
    }, true, true);
    // 注册PointerUp事件
    addBtn.AddEventTrigger(EventTriggerType.PointerUp, _ => { isPress = false; }, false, true);

    subBtn.AddEventTrigger(EventTriggerType.PointerDown, _ =>
    {
        isPress = true;
        StartCoroutine(Press(false));
    }, true, true);
    subBtn.AddEventTrigger(EventTriggerType.PointerUp, _ => { isPress = false; }, false, false);
}

  效果图:


Result.gif

  以上

上一篇下一篇

猜你喜欢

热点阅读