using System; using System.Collections.Generic; using CriWare; using Sirenix.Utilities; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.InputSystem.UI; using UnityEngine.UIElements; public class ButtonEx: MonoBehaviour, IPointerUpHandler, IPointerDownHandler, IDragHandler, IBeginDragHandler, IEndDragHandler { private bool _isPressed; private bool _isLastFramePressed; private float _pressedTime; private const float MinDelta = 0.0001f; private const float MinLongPressTime = 0.35f; private const float MinUpDelta = 1f; private List _pointerEventDatas = new(); private PointerEventData _curPointerEventData; #region 继承滑动、按下抬起 public delegate void BeginDrag(PointerEventData eventData); public delegate void OnDragging(PointerEventData eventData); public delegate void EndDrag(PointerEventData eventData); public delegate void OnPointUp(PointerEventData eventData); public delegate void OnPointDown(PointerEventData eventData); public BeginDrag beginDrag; public OnDragging onDragging; public EndDrag endDrag; public OnPointUp onPointUp; public OnPointDown onPointDown; public void OnPointerUp(PointerEventData eventData) { // if (eventData.pointerId >= 0) // { // DebugUtil.LogError("OnPointerUp eventData.pointerId = " + eventData.pointerId); // return; // } if (_pressedTime < MinLongPressTime) { if (_bOnClick) { onClick?.Invoke(); _bOnClick = false; } } _curPointerEventData = null; _isPressed = false; _bLongPress = true; _bUpDrag = true; onPointUp?.Invoke(eventData); } public void OnPointerDown(PointerEventData eventData) { // if (eventData.pointerId >= 0) // { // DebugUtil.LogError("OnPointerUp eventData.pointerId = " + eventData.pointerId); // return; // } _curPointerEventData = eventData; _isPressed = true; _bLongPress = true; _bUpDrag = true; _startPos = eventData.pressPosition; onPointDown?.Invoke(eventData); } public void OnDrag(PointerEventData eventData) { if (eventData.pointerId < 0) { _curPointerEventData = eventData; } onDragging?.Invoke(eventData); } public void OnBeginDrag(PointerEventData eventData) { if (eventData.pointerId < 0) { _curPointerEventData = eventData; } beginDrag?.Invoke(eventData); } public void OnEndDrag(PointerEventData eventData) { if (eventData.pointerId < 0) { _curPointerEventData = eventData; } endDrag?.Invoke(eventData); } public void AddPointerUp(Action action) { onPointUp += (eventData) => { action?.Invoke(eventData); }; } public void AddPointerDown(Action action) { onPointDown += (eventData) => { action?.Invoke(eventData); }; } public void AddBeginDrag(Action action) { beginDrag += (eventData) => { action?.Invoke(eventData); }; } public void AddOnDrag(Action action) { onDragging += (eventData) => { action?.Invoke(eventData); }; } public void AddEndDrag(Action action) { endDrag += (eventData) => { action?.Invoke(eventData); }; } #endregion #region 扩展上滑、长按 private bool _bUpDrag; private bool _bLongPress; private bool _bOnClick; public delegate void OnUpDrag(); public delegate void OnLongPress(); public delegate void OnClick(); public OnUpDrag onUpDrag; public OnLongPress onLongPress; public OnClick onClick; private Vector2 _startPos; private Vector2 _curPos; public void AddLongPress(Action action) { onLongPress += () => { action?.Invoke(); }; } public void AddUpDrag(Action action) { onUpDrag += () => { action?.Invoke(); }; } public void AddUpDrag(Action action, T param) { onUpDrag += () => { action?.Invoke(param); }; } #endregion private void Update() { if (!_isPressed) { _bOnClick = false; _isLastFramePressed = false; _pressedTime = 0f; return; } if (_isPressed) { _curPos = _curPointerEventData.position; //长按 if (_bLongPress) { var disSqr = (_curPos - _startPos).sqrMagnitude; if (disSqr > MinDelta) { _bLongPress = false; _bOnClick = false; } else { if (_pressedTime > MinLongPressTime) { onLongPress?.Invoke(); _bLongPress = false; } } } //上滑 if (_bUpDrag) { var disSqrY = Mathf.Sqrt(_curPos.y - _startPos.y); var disSqrX = Mathf.Sqrt(_curPos.x - _startPos.x); if (disSqrY > MinUpDelta && disSqrX < disSqrY / 2) { onUpDrag?.Invoke(); _bUpDrag = false; } } _pressedTime += Time.deltaTime; if (!_isLastFramePressed) { _isLastFramePressed = true; } } } public void RemoveAll() { } private void OnDestroy() { } }