UGUI常用事件封装整理

1. EventTriggerListener

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class EventTriggerListener : EventTrigger
{
    public delegate void VoidDelegate(GameObject go);
    public delegate void BoolDelegate(GameObject go, bool state);
    public delegate void FloatDelegate(GameObject go, float delta);
    public delegate void VectorDelegate(GameObject go, Vector2 delta);
    public delegate void ObjectDelegate(GameObject go, GameObject obj);
    public delegate void KeyCodeDelegate(GameObject go, KeyCode key);
    public delegate void EventDataDelegate(PointerEventData eventData);

    public VoidDelegate onClick;
    public VoidDelegate onDown;
    public VoidDelegate onEnter;
    public VoidDelegate onExit;
    public VoidDelegate onUp;
    public VoidDelegate onSelect;
    public VoidDelegate onUpdateSelect;

    public EventDataDelegate onDrag;
    public EventDataDelegate onBeginDrag;
    public EventDataDelegate onEndDrag;
    public EventDataDelegate onDrop;

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

    static public EventTriggerListener Get(Transform transform)
    {
        EventTriggerListener listener = transform.GetComponent<EventTriggerListener>();
        if (listener == null) listener = transform.gameObject.AddComponent<EventTriggerListener>();
        return listener;
    }
    public override void OnPointerClick(PointerEventData eventData)
    {
        if (onClick != null && !eventData.dragging) onClick(gameObject);
    }
    public override void OnPointerDown(PointerEventData eventData)
    {
        if (onDown != null) onDown(gameObject);
    }
    public override void OnPointerEnter(PointerEventData eventData)
    {
        if (onEnter != null) onEnter(gameObject);
    }
    public override void OnPointerExit(PointerEventData eventData)
    {
        if (onExit != null) onExit(gameObject);
    }
    public override void OnPointerUp(PointerEventData eventData)
    {
        if (onUp != null) onUp(gameObject);
    }
    public override void OnSelect(BaseEventData eventData)
    {
        if (onSelect != null) onSelect(gameObject);
    }
    public override void OnUpdateSelected(BaseEventData eventData)
    {
        if (onUpdateSelect != null) onUpdateSelect(gameObject);
    }
    public override void OnDrag(PointerEventData eventData)
    {
        if (onDrag != null) onDrag(eventData);
    }

    public override void OnBeginDrag(PointerEventData eventData)
    {
        if (onBeginDrag != null) onBeginDrag(eventData);
    }

    public override void OnEndDrag(PointerEventData eventData)
    {
        if (onEndDrag != null) onEndDrag(eventData);
    }

    public override void OnDrop(PointerEventData eventData)
    {
        if (onDrop != null) onDrop(eventData);
    }
}

2、按钮长按事件处理

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

public class ButtonPress : Button
{
    public bool isPointerDown = false;
    private float timePressStarted;
    private float durationThreshold = 0.2f; // 长按的阈值时间
 
    public UnityEvent OnPress = new UnityEvent(); // 长按事件
    public UnityEvent OnPressEnd = new UnityEvent(); // 长按结束事件
 
    private void Update()
    {
        if (isPointerDown)
        {
            if (Time.time - timePressStarted > durationThreshold)
            {
                OnPress.Invoke(); 
            }
        }
    }
 
    public override void OnPointerDown(PointerEventData eventData)
    {
        base.OnPointerDown(eventData);
        if (eventData.button != PointerEventData.InputButton.Left)
            return;
 
        timePressStarted = Time.time;
        isPointerDown = true;
    }
 
    public override void OnPointerUp(PointerEventData eventData)
    {
        base.OnPointerUp(eventData);
        isPointerDown = false;
        OnPressEnd.Invoke();
    }
}

上述代码ButtonPress也可改为继承自MonoBehaviour,通过挂接的方式实现,而不是替换Button组件,可降低侵入性。

3、按钮长按、双击等多种事件合集

using System;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class ExButton : Button
{
    private enum EnumExButtonState
    {
        /// <summary>空</summary>
        None,
        /// <summary>鼠标按下</summary>
        PointerDown,
        /// <summary>鼠标按下</summary>
        PointerUp,
        /// <summary>单击</summary>
        Click,
        /// <summary>双击</summary>
        DoubleClick,
        /// <summary>长按开始</summary>
        PressBegin,
        /// <summary>长按</summary>
        Press,
        /// <summary>长按结束</summary>
        PressEnd,
    }
 
    /// <summary>按钮状态</summary>
    private EnumExButtonState mButtonState = EnumExButtonState.None;
    /// <summary>鼠标按下时间</summary>
    private float mPointerDownTime = 0.0f;
    [SerializeField]
    /// <summary>双击间隔时间</summary>
    private float mDoubleClickInterval = 0.2f;
    [SerializeField]
    /// <summary>长按开始时间</summary>
    private float mPressBeginTime = 0.3f;
    [SerializeField]
    /// <summary>长按间隔时间,0为每帧调用</summary>
    private float mPressIntervalTime = 0.2f;
    /// <summary>长按缓存时间</summary>
    private float mPressCacheTime = 0f;
 
    public Action OnClick { get; set; }
    public Action OnDoubleClick { get; set; }
    public Action OnPressBegin { get; set; }
    public Action OnPress { get; set; }
    public Action OnPressEnd { get; set; }
 
    public override void OnPointerDown(PointerEventData eventData)
    {
        base.OnPointerDown(eventData);
 
        if (OnDoubleClick != null)
        {
            if (mButtonState == EnumExButtonState.None)
            {
                mButtonState = EnumExButtonState.PointerDown;
                mPointerDownTime = Time.time;
            }
            else if (mButtonState == EnumExButtonState.PointerUp)
            {
                if (Time.time - mPointerDownTime < mDoubleClickInterval)
                {
                    mButtonState = EnumExButtonState.DoubleClick;
                    return;
                }
                else
                {
                    mButtonState = EnumExButtonState.PointerDown;
                    mPointerDownTime = Time.time;
                }
            }
        }
 
        if (OnPressBegin != null || OnPress != null || OnPressEnd != null)
        {
            if (mButtonState != EnumExButtonState.DoubleClick)
            {
                mButtonState = EnumExButtonState.PointerDown;
                mPointerDownTime = Time.time;
            }
        }
 
        if (OnClick != null)
        {
            mButtonState = EnumExButtonState.PointerDown;
        }
    }
 
    public override void OnPointerUp(PointerEventData eventData)
    {
        base.OnPointerUp(eventData);
 
        if (OnDoubleClick != null)
        {
            if (mButtonState == EnumExButtonState.PointerDown)
            {
                mButtonState = EnumExButtonState.PointerUp;
                return;
            }
            else if (mButtonState == EnumExButtonState.DoubleClick)
            {
                return;
            }
        }
 
        if (OnPressBegin != null || OnPress != null || OnPressEnd != null)
        {
            if (mButtonState == EnumExButtonState.Press)
            {
                mButtonState = EnumExButtonState.PressEnd;
                return;
            }
        }
 
        if (OnClick != null)
        {
            if (mButtonState == EnumExButtonState.PointerDown)
                mButtonState = EnumExButtonState.PointerUp;
        }
    }
 
    private void Update()
    {
        ProcessUpdate();
        ResponseButtonState();
    }
 
    private void ProcessUpdate()
    {
        if (OnDoubleClick != null) { }
 
        if (OnPressBegin != null || OnPress != null || OnPressEnd != null)
        {
            if (mButtonState == EnumExButtonState.PointerDown)
            {
                if (Time.time - mPointerDownTime > mPressBeginTime)
                {
                    mButtonState = EnumExButtonState.PressBegin;
                    mPressCacheTime = 0f;
                    return;
                }
            }
        }
 
        if (OnClick != null)
        {
            if (mButtonState == EnumExButtonState.PointerUp)
            {
                if (OnDoubleClick != null)
                {
                    if (Time.time - mPointerDownTime > mDoubleClickInterval)
                        mButtonState = EnumExButtonState.Click;
                }
                else
                {
                    mButtonState = EnumExButtonState.Click;
                }
            }
        }
    }
 
    private void ResponseButtonState()
    {
        switch (mButtonState)
        {
            case EnumExButtonState.None:
                break;
            case EnumExButtonState.Click:
                OnClick?.Invoke();
                mButtonState = EnumExButtonState.None;
                break;
            case EnumExButtonState.DoubleClick:
                OnDoubleClick?.Invoke();
                mButtonState = EnumExButtonState.None;
                break;
            case EnumExButtonState.PressBegin:
                OnPressBegin?.Invoke();
                mButtonState = EnumExButtonState.Press;
                break;
            case EnumExButtonState.Press:
                {
                    mPressCacheTime += Time.deltaTime;
                    if (mPressCacheTime >= mPressIntervalTime)
                    {
                        mPressCacheTime = mPressCacheTime - mPressIntervalTime;
                        OnPress?.Invoke();
                    }
                    break;
                }
            case EnumExButtonState.PressEnd:
                OnPressEnd?.Invoke();
                mButtonState = EnumExButtonState.None;
                break;
            default:
                break;
        }
    }
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用Unity UGUI创建可滚动列表的封装代码: ```csharp using UnityEngine; using UnityEngine.UI; using System.Collections.Generic; public class ScrollableList : MonoBehaviour { public GameObject listItemPrefab; public Transform contentPanel; public ScrollRect scrollRect; private List<GameObject> listItems = new List<GameObject>(); public void AddListItem(string text) { GameObject listItem = Instantiate(listItemPrefab) as GameObject; listItem.transform.SetParent(contentPanel, false); listItem.GetComponent<Text>().text = text; listItems.Add(listItem); UpdateContentSize(); } public void RemoveListItem(int index) { if (index >= 0 && index < listItems.Count) { Destroy(listItems[index]); listItems.RemoveAt(index); UpdateContentSize(); } } public void ClearList() { foreach (GameObject listItem in listItems) { Destroy(listItem); } listItems.Clear(); UpdateContentSize(); } private void UpdateContentSize() { GridLayoutGroup gridLayout = contentPanel.GetComponent<GridLayoutGroup>(); float cellSize = gridLayout.cellSize.y + gridLayout.spacing.y; float spacing = gridLayout.padding.top + gridLayout.padding.bottom + gridLayout.spacing.y; int rowCount = Mathf.CeilToInt(listItems.Count / (float)gridLayout.constraintCount); float height = rowCount * cellSize + spacing; contentPanel.GetComponent<RectTransform>().sizeDelta = new Vector2(0, height); } } ``` 在这个封装代码中,我们将创建、添加、删除和清空列表项的功能封装成了公共函数。当添加、删除、或清空列表项时,我们都会调用`UpdateContentSize()`函数来重新计算内容面板的大小并设置为`contentPanel`的大小。这样,我们就可以在脚本中方便地使用这个可滚动列表了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值