当前位置:   article > 正文

[Unity案例]Button的双击和长按_unity button 长按检测

unity button 长按检测

实现内容:

扩展Unity自带的Button组件,在原有的单击事件的基础上实现双击和长按效果;

替换Button组件,通过单选框选择当前执行哪一种事件
替换Button组件,通过单选框选择当前执行哪一种事件

代码详解:

  1. 单击事件处理:
    • 通过singleClickEnabled开关控制是否启用单击事件。
    • OnPointerClick方法中,根据按钮的激活状态和可交互状态执行单击事件。
    • 使用Unity的Profiler API添加标记,并触发按钮的单击事件回调。
  2. 双击事件处理:
    • 通过doubleClickEnabled开关控制是否启用双击事件。
    • OnPointerClick方法中,记录点击次数,并根据双击时间阈值判断是否触发双击事件。
    • 如果检测到双击,添加Profiler标记,触发双击事件回调,并重置点击计数。
  3. 长按事件处理:
    • 通过longPressEnabled开关控制是否启用长按事件。
    • OnPointerDown方法中,记录按下时间,并标记长按状态。
    • OnPointerUp方法中,重置长按状态。
    • 使用Update方法定期检测长按,如果达到长按时间阈值,则触发长按事件回调。
  4. 事件回调:
    • 使用ButtonClickedEvent类型的事件回调,可在Inspector中配置。
    • 提供了单击、双击和长按的事件回调,可通过Inspector或代码设置。

完整代码如下:

  1. using UnityEngine;
  2. using UnityEngine.EventSystems;
  3. using UnityEngine.Serialization;
  4. using UnityEngine.UI;
  5. public class ButtonExtension : Button
  6. {
  7. #region 单机双击相关
  8. public bool singleClickEnabled = true;
  9. public bool doubleClickEnabled = false;
  10. public float doubleClickTime = 0.3f;
  11. private float lastClickTime = float.NegativeInfinity;
  12. private int clickCount = 0;
  13. [FormerlySerializedAs("onDoubleClick")]
  14. [SerializeField]
  15. private ButtonClickedEvent doubleClickEvent = new ();
  16. public ButtonClickedEvent onDoubleClick
  17. {
  18. get => doubleClickEvent;
  19. set => doubleClickEvent = value;
  20. }
  21. public override void OnPointerClick(PointerEventData eventData)
  22. {
  23. if(!IsActive() && !interactable)
  24. return;
  25. if (singleClickEnabled)
  26. {
  27. UISystemProfilerApi.AddMarker("Button.onClick", this);
  28. onClick?.Invoke();
  29. Debug.LogError("单击");
  30. }
  31. if (doubleClickEnabled)
  32. {
  33. clickCount++;
  34. if (clickCount >= 2)
  35. {
  36. if (Time.realtimeSinceStartup - lastClickTime < doubleClickTime)
  37. {
  38. UISystemProfilerApi.AddMarker("Button.onDoubleClick", this);
  39. onDoubleClick?.Invoke();
  40. Debug.LogError("双击");
  41. lastClickTime = float.NegativeInfinity;
  42. clickCount = 0;
  43. }
  44. else
  45. {
  46. clickCount = 1;
  47. lastClickTime = Time.unscaledTime;
  48. }
  49. }
  50. else
  51. {
  52. lastClickTime = Time.unscaledTime;
  53. }
  54. }
  55. }
  56. #endregion
  57. #region 长按相关
  58. public bool longPressEnabled = false;
  59. private float lastPressTime = 0;
  60. public float minPressTime = 0.5f;
  61. private bool isPressing = false;
  62. private bool hasInvokedLongPress = false;
  63. [FormerlySerializedAs("onLongPress")]
  64. [SerializeField]
  65. private ButtonClickedEvent longPressEvent = new();
  66. public ButtonClickedEvent onLongPress
  67. {
  68. get => longPressEvent;
  69. set => longPressEvent = value;
  70. }
  71. public override void OnPointerDown(PointerEventData eventData)
  72. {
  73. base.OnPointerDown(eventData);
  74. if (longPressEnabled)
  75. {
  76. hasInvokedLongPress = false;
  77. isPressing = true;
  78. lastPressTime = Time.unscaledTime;
  79. }
  80. }
  81. public override void OnPointerUp(PointerEventData eventData)
  82. {
  83. base.OnPointerUp(eventData);
  84. isPressing = false;
  85. hasInvokedLongPress = false;
  86. }
  87. private void Update()
  88. {
  89. DealLongPress();
  90. }
  91. private void DealLongPress()
  92. {
  93. if(hasInvokedLongPress) return;
  94. if (isPressing)
  95. {
  96. if (Time.unscaledTime - lastPressTime >= minPressTime)
  97. {
  98. UISystemProfilerApi.AddMarker("Button.onLongPress", this);
  99. onLongPress?.Invoke();
  100. hasInvokedLongPress = true;
  101. Debug.LogError("执行长按事件");
  102. }
  103. }
  104. }
  105. #endregion
  106. }

将新增的属性添加到Inspector面板,具体代码如下:

  1. using UnityEngine;
  2. namespace UnityEditor.UI
  3. {
  4. [CustomEditor(typeof(ButtonExtension), true)]
  5. [CanEditMultipleObjects]
  6. public class ButtonExInspector : SelectableEditor
  7. {
  8. private ButtonExtension buttonExtension;
  9. SerializedProperty onDoubleClickProperty;
  10. SerializedProperty onClickProperty;
  11. SerializedProperty onLongPressProperty;
  12. protected override void OnEnable()
  13. {
  14. base.OnEnable();
  15. onDoubleClickProperty = serializedObject.FindProperty("doubleClickEvent");
  16. onClickProperty = serializedObject.FindProperty("m_OnClick");
  17. onLongPressProperty = serializedObject.FindProperty("longPressEvent");
  18. }
  19. public override void OnInspectorGUI()
  20. {
  21. base.OnInspectorGUI();
  22. serializedObject.Update();
  23. buttonExtension = (ButtonExtension)target;
  24. EditorGUILayout.Space();
  25. buttonExtension.singleClickEnabled = EditorGUILayout.Toggle("启用单击", buttonExtension.singleClickEnabled);
  26. if (buttonExtension.singleClickEnabled)
  27. {
  28. buttonExtension.doubleClickEnabled = false;
  29. buttonExtension.longPressEnabled = false;
  30. EditorGUILayout.PropertyField(onClickProperty);
  31. }
  32. buttonExtension.doubleClickEnabled = EditorGUILayout.Toggle("启用双击", buttonExtension.doubleClickEnabled);
  33. if (buttonExtension.doubleClickEnabled)
  34. {
  35. buttonExtension.doubleClickTime = EditorGUILayout.FloatField("双击间隔", buttonExtension.doubleClickTime);
  36. buttonExtension.singleClickEnabled = false;
  37. buttonExtension.longPressEnabled = false;
  38. EditorGUILayout.PropertyField(onDoubleClickProperty);
  39. }
  40. buttonExtension.longPressEnabled = EditorGUILayout.Toggle("启用长按", buttonExtension.longPressEnabled);
  41. if(buttonExtension.longPressEnabled)
  42. {
  43. buttonExtension.minPressTime = EditorGUILayout.FloatField("长按时间", buttonExtension.minPressTime);
  44. buttonExtension.singleClickEnabled = false;
  45. buttonExtension.doubleClickEnabled = false;
  46. EditorGUILayout.PropertyField(onLongPressProperty);
  47. }
  48. serializedObject.ApplyModifiedProperties();
  49. if(GUI.changed)
  50. EditorUtility.SetDirty(target);
  51. }
  52. }
  53. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/爱喝兽奶帝天荒/article/detail/849879
推荐阅读
相关标签
  

闽ICP备14008679号