实现内容:
扩展Unity自带的Button组件,在原有的单击事件的基础上实现双击和长按效果;文章来源地址https://www.toymoban.com/news/detail-858437.html
代码详解:
-
单击事件处理:
- 通过
singleClickEnabled
开关控制是否启用单击事件。 - 在
OnPointerClick
方法中,根据按钮的激活状态和可交互状态执行单击事件。 - 使用Unity的Profiler API添加标记,并触发按钮的单击事件回调。
- 通过
-
双击事件处理:
- 通过
doubleClickEnabled
开关控制是否启用双击事件。 - 在
OnPointerClick
方法中,记录点击次数,并根据双击时间阈值判断是否触发双击事件。 - 如果检测到双击,添加Profiler标记,触发双击事件回调,并重置点击计数。
- 通过
-
长按事件处理:
- 通过
longPressEnabled
开关控制是否启用长按事件。 - 在
OnPointerDown
方法中,记录按下时间,并标记长按状态。 - 在
OnPointerUp
方法中,重置长按状态。 - 使用
Update
方法定期检测长按,如果达到长按时间阈值,则触发长按事件回调。
- 通过
-
事件回调:
- 使用
ButtonClickedEvent
类型的事件回调,可在Inspector中配置。 - 提供了单击、双击和长按的事件回调,可通过Inspector或代码设置。
- 使用
完整代码如下:
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Serialization;
using UnityEngine.UI;
public class ButtonExtension : Button
{
#region 单机双击相关
public bool singleClickEnabled = true;
public bool doubleClickEnabled = false;
public float doubleClickTime = 0.3f;
private float lastClickTime = float.NegativeInfinity;
private int clickCount = 0;
[FormerlySerializedAs("onDoubleClick")]
[SerializeField]
private ButtonClickedEvent doubleClickEvent = new ();
public ButtonClickedEvent onDoubleClick
{
get => doubleClickEvent;
set => doubleClickEvent = value;
}
public override void OnPointerClick(PointerEventData eventData)
{
if(!IsActive() && !interactable)
return;
if (singleClickEnabled)
{
UISystemProfilerApi.AddMarker("Button.onClick", this);
onClick?.Invoke();
Debug.LogError("单击");
}
if (doubleClickEnabled)
{
clickCount++;
if (clickCount >= 2)
{
if (Time.realtimeSinceStartup - lastClickTime < doubleClickTime)
{
UISystemProfilerApi.AddMarker("Button.onDoubleClick", this);
onDoubleClick?.Invoke();
Debug.LogError("双击");
lastClickTime = float.NegativeInfinity;
clickCount = 0;
}
else
{
clickCount = 1;
lastClickTime = Time.unscaledTime;
}
}
else
{
lastClickTime = Time.unscaledTime;
}
}
}
#endregion
#region 长按相关
public bool longPressEnabled = false;
private float lastPressTime = 0;
public float minPressTime = 0.5f;
private bool isPressing = false;
private bool hasInvokedLongPress = false;
[FormerlySerializedAs("onLongPress")]
[SerializeField]
private ButtonClickedEvent longPressEvent = new();
public ButtonClickedEvent onLongPress
{
get => longPressEvent;
set => longPressEvent = value;
}
public override void OnPointerDown(PointerEventData eventData)
{
base.OnPointerDown(eventData);
if (longPressEnabled)
{
hasInvokedLongPress = false;
isPressing = true;
lastPressTime = Time.unscaledTime;
}
}
public override void OnPointerUp(PointerEventData eventData)
{
base.OnPointerUp(eventData);
isPressing = false;
hasInvokedLongPress = false;
}
private void Update()
{
DealLongPress();
}
private void DealLongPress()
{
if(hasInvokedLongPress) return;
if (isPressing)
{
if (Time.unscaledTime - lastPressTime >= minPressTime)
{
UISystemProfilerApi.AddMarker("Button.onLongPress", this);
onLongPress?.Invoke();
hasInvokedLongPress = true;
Debug.LogError("执行长按事件");
}
}
}
#endregion
}
将新增的属性添加到Inspector面板,具体代码如下:
using UnityEngine;
namespace UnityEditor.UI
{
[CustomEditor(typeof(ButtonExtension), true)]
[CanEditMultipleObjects]
public class ButtonExInspector : SelectableEditor
{
private ButtonExtension buttonExtension;
SerializedProperty onDoubleClickProperty;
SerializedProperty onClickProperty;
SerializedProperty onLongPressProperty;
protected override void OnEnable()
{
base.OnEnable();
onDoubleClickProperty = serializedObject.FindProperty("doubleClickEvent");
onClickProperty = serializedObject.FindProperty("m_OnClick");
onLongPressProperty = serializedObject.FindProperty("longPressEvent");
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
serializedObject.Update();
buttonExtension = (ButtonExtension)target;
EditorGUILayout.Space();
buttonExtension.singleClickEnabled = EditorGUILayout.Toggle("启用单击", buttonExtension.singleClickEnabled);
if (buttonExtension.singleClickEnabled)
{
buttonExtension.doubleClickEnabled = false;
buttonExtension.longPressEnabled = false;
EditorGUILayout.PropertyField(onClickProperty);
}
buttonExtension.doubleClickEnabled = EditorGUILayout.Toggle("启用双击", buttonExtension.doubleClickEnabled);
if (buttonExtension.doubleClickEnabled)
{
buttonExtension.doubleClickTime = EditorGUILayout.FloatField("双击间隔", buttonExtension.doubleClickTime);
buttonExtension.singleClickEnabled = false;
buttonExtension.longPressEnabled = false;
EditorGUILayout.PropertyField(onDoubleClickProperty);
}
buttonExtension.longPressEnabled = EditorGUILayout.Toggle("启用长按", buttonExtension.longPressEnabled);
if(buttonExtension.longPressEnabled)
{
buttonExtension.minPressTime = EditorGUILayout.FloatField("长按时间", buttonExtension.minPressTime);
buttonExtension.singleClickEnabled = false;
buttonExtension.doubleClickEnabled = false;
EditorGUILayout.PropertyField(onLongPressProperty);
}
serializedObject.ApplyModifiedProperties();
if(GUI.changed)
EditorUtility.SetDirty(target);
}
}
}
文章来源:https://www.toymoban.com/news/detail-858437.html
到了这里,关于[Unity案例]Button的双击和长按的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!