This commit is contained in:
陈思海 2025-04-17 16:03:39 +08:00
parent d44c1ad80a
commit 52a8c7358a
6 changed files with 44 additions and 206 deletions

View File

@ -9,30 +9,11 @@
public class UIButtonSuperEditor : ButtonEditor public class UIButtonSuperEditor : ButtonEditor
{ {
private SerializedProperty m_ButtonUISounds; private SerializedProperty m_ButtonUISounds;
private SerializedProperty m_CanClick;
private SerializedProperty m_CanDoubleClick;
private SerializedProperty m_DoubleClickIntervalTime;
private SerializedProperty onDoubleClick;
private SerializedProperty m_CanLongPress;
private SerializedProperty m_ResponseOnceByPress;
private SerializedProperty m_LongPressDurationTime;
private SerializedProperty onPress;
protected override void OnEnable() protected override void OnEnable()
{ {
base.OnEnable(); base.OnEnable();
m_ButtonUISounds = serializedObject.FindProperty("m_ButtonUISounds"); m_ButtonUISounds = serializedObject.FindProperty("m_ButtonUISounds");
m_CanClick = serializedObject.FindProperty("m_CanClick");
m_CanDoubleClick = serializedObject.FindProperty("m_CanDoubleClick");
m_DoubleClickIntervalTime = serializedObject.FindProperty("m_DoubleClickIntervalTime");
onDoubleClick = serializedObject.FindProperty("onDoubleClick");
m_CanLongPress = serializedObject.FindProperty("m_CanLongPress");
m_ResponseOnceByPress = serializedObject.FindProperty("m_ResponseOnceByPress");
m_LongPressDurationTime = serializedObject.FindProperty("m_LongPressDurationTime");
onPress = serializedObject.FindProperty("onPress");
} }
public override void OnInspectorGUI() public override void OnInspectorGUI()
@ -40,16 +21,6 @@
base.OnInspectorGUI(); base.OnInspectorGUI();
serializedObject.Update(); serializedObject.Update();
EditorGUILayout.PropertyField(m_ButtonUISounds); //显示我们创建的属性 EditorGUILayout.PropertyField(m_ButtonUISounds); //显示我们创建的属性
EditorGUILayout.PropertyField(m_CanClick); //显示我们创建的属性
EditorGUILayout.Space(); //空行
EditorGUILayout.PropertyField(m_CanDoubleClick); //显示我们创建的属性
EditorGUILayout.PropertyField(m_DoubleClickIntervalTime); //显示我们创建的属性
EditorGUILayout.PropertyField(onDoubleClick); //显示我们创建的属性
EditorGUILayout.Space(); //空行
EditorGUILayout.PropertyField(m_CanLongPress); //显示我们创建的属性
EditorGUILayout.PropertyField(m_ResponseOnceByPress); //显示我们创建的属性
EditorGUILayout.PropertyField(m_LongPressDurationTime); //显示我们创建的属性
EditorGUILayout.PropertyField(onPress); //显示我们创建的属性
serializedObject.ApplyModifiedProperties(); serializedObject.ApplyModifiedProperties();
} }
} }

View File

@ -1,4 +1,5 @@
using System; using System;
using AlicizaX.UI.Extension;
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
@ -37,16 +38,11 @@ namespace AlicizaX.UI.RecyclerView
public virtual void BindItemClick<T>(T data, Action<T> action) public virtual void BindItemClick<T>(T data, Action<T> action)
{ {
if (TryGetComponent(out Button button)) if (TryGetComponent(out IButton button))
{ {
button.onClick.RemoveAllListeners(); button.onClick.RemoveAllListeners();
button.onClick.AddListener(() => action?.Invoke(data)); button.onClick.AddListener(() => action?.Invoke(data));
} }
else if (TryGetComponent(out UXButton uxButton))
{
uxButton.onClick.RemoveAllListeners();
uxButton.onClick.AddListener(() => action?.Invoke(data));
}
} }
protected internal void BindChoiceState(bool state) protected internal void BindChoiceState(bool state)

View File

@ -13,8 +13,7 @@ namespace AlicizaX.UI.Extension
Up, Up,
Click, Click,
Enter, Enter,
Exit, Exit
Drag
} }
[Serializable] [Serializable]
@ -24,131 +23,10 @@ namespace AlicizaX.UI.Extension
public string ButtonUISoundName = ""; public string ButtonUISoundName = "";
} }
public delegate void ButtonBeginDragCallback(PointerEventData eventData); public class UIButtonSuper : Button,IButton
public delegate void ButtonDragCallback(PointerEventData eventData);
public delegate void ButtonEndDragCallback(PointerEventData eventData);
public class UIButtonSuper : Button, IBeginDragHandler, IDragHandler, IEndDragHandler
{ {
public List<ButtonSoundCell> m_ButtonUISounds = new List<ButtonSoundCell>(); public List<ButtonSoundCell> m_ButtonUISounds = new List<ButtonSoundCell>();
[Tooltip("是否可以点击")] public bool m_CanClick = true;
[Tooltip("是否可以双击")] public bool m_CanDoubleClick = false;
[Tooltip("双击间隔时长")] public float m_DoubleClickIntervalTime = 0.1f;
[Tooltip("双击事件")] public ButtonClickedEvent onDoubleClick;
[Tooltip("是否可以长按")] public bool m_CanLongPress = false;
[Tooltip("长按是否只响应一次")] public bool m_ResponseOnceByPress = false;
[Tooltip("长按满足间隔")] public float m_LongPressDurationTime = 1;
[Tooltip("长按事件")] public ButtonClickedEvent onPress;
//public ButtonClickedEvent onClick;
public ButtonBeginDragCallback onBeginDrag;
public ButtonDragCallback onDrag;
public ButtonEndDragCallback onEndDrag;
private bool isDown = false;
private bool isPress = false;
private bool isDownExit = false;
private float downTime = 0;
private int fingerId = int.MinValue;
public bool IsDraging
{
get { return fingerId != int.MinValue; }
} //摇杆拖拽状态
public int FingerId
{
get { return fingerId; }
}
private float clickIntervalTime = 0;
private int clickTimes = 0;
void Update()
{
if (isDown)
{
if (!m_CanLongPress)
{
return;
}
if (m_ResponseOnceByPress && isPress)
{
return;
}
downTime += Time.deltaTime;
if (downTime > m_LongPressDurationTime)
{
isPress = true;
onPress.Invoke();
}
}
if (clickTimes >= 1)
{
if (!m_CanLongPress && !m_CanDoubleClick && m_CanClick)
{
onClick.Invoke();
clickTimes = 0;
}
else
{
clickIntervalTime += Time.deltaTime;
if (clickIntervalTime >= m_DoubleClickIntervalTime)
{
if (clickTimes >= 2)
{
if (m_CanDoubleClick)
{
onDoubleClick.Invoke();
}
}
else
{
if (m_CanClick)
{
onClick.Invoke();
}
}
clickTimes = 0;
clickIntervalTime = 0;
}
}
}
}
/// <summary>
/// 是否按钮按下
/// </summary>
public bool IsDown
{
get { return isDown; }
}
/// <summary>
/// 是否按钮长按
/// </summary>
public bool IsPress
{
get { return isPress; }
}
/// <summary>
/// 是否按钮按下后离开按钮位置
/// </summary>
public bool IsDownExit
{
get { return isDownExit; }
}
public ButtonSoundCell GetButtonSound(ButtonSoundType buttonSoundType) public ButtonSoundCell GetButtonSound(ButtonSoundType buttonSoundType)
{ {
foreach (var buttonSound in m_ButtonUISounds) foreach (var buttonSound in m_ButtonUISounds)
@ -182,59 +60,26 @@ namespace AlicizaX.UI.Extension
public override void OnPointerDown(PointerEventData eventData) public override void OnPointerDown(PointerEventData eventData)
{ {
base.OnPointerDown(eventData); base.OnPointerDown(eventData);
if (eventData.pointerId < -1 || IsDraging) return; //适配 Touch只响应一个Touch适配鼠标只响应左键
fingerId = eventData.pointerId;
isDown = true;
isDownExit = false;
downTime = 0;
PlayButtonSound(ButtonSoundType.Down); PlayButtonSound(ButtonSoundType.Down);
} }
public override void OnPointerUp(PointerEventData eventData) public override void OnPointerUp(PointerEventData eventData)
{ {
base.OnPointerUp(eventData); base.OnPointerUp(eventData);
if (fingerId != eventData.pointerId) return; //正确的手指抬起时才会;
fingerId = int.MinValue;
isDown = false;
isDownExit = true;
PlayButtonSound(ButtonSoundType.Up); PlayButtonSound(ButtonSoundType.Up);
} }
public override void OnPointerExit(PointerEventData eventData) public override void OnPointerExit(PointerEventData eventData)
{ {
base.OnPointerExit(eventData); base.OnPointerExit(eventData);
if (fingerId != eventData.pointerId) return; //正确的手指抬起时才会;
isPress = false;
isDownExit = true;
PlayButtonSound(ButtonSoundType.Exit); PlayButtonSound(ButtonSoundType.Exit);
} }
public override void OnPointerClick(PointerEventData eventData) public override void OnPointerClick(PointerEventData eventData)
{ {
if (!isPress) base.OnPointerClick(eventData);
{
clickTimes += 1;
}
else
isPress = false;
PlayButtonSound(ButtonSoundType.Click); PlayButtonSound(ButtonSoundType.Click);
} }
public void OnBeginDrag(PointerEventData eventData)
{
onBeginDrag?.Invoke(eventData);
}
public void OnDrag(PointerEventData eventData)
{
PlayButtonSound(ButtonSoundType.Drag);
onDrag?.Invoke(eventData);
}
public void OnEndDrag(PointerEventData eventData)
{
onEndDrag?.Invoke(eventData);
}
} }
} }

View File

@ -0,0 +1,9 @@
using UnityEngine.UI;
namespace AlicizaX.UI.Extension
{
public interface IButton
{
Button.ButtonClickedEvent onClick { get; set; }
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 06a9d41d8ef2435395bf49fd7463aba6
timeCreated: 1744867171

View File

@ -63,14 +63,18 @@ internal enum SelectionState
[DisallowMultipleComponent] [DisallowMultipleComponent]
[RequireComponent(typeof(Graphic))] [RequireComponent(typeof(Graphic))]
public class UXButton : UIBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerEnterHandler, IPointerExitHandler public class UXButton : UIBehaviour, IButton,
IPointerDownHandler,
IPointerUpHandler,
IPointerEnterHandler,
IPointerExitHandler,
IPointerClickHandler
{ {
[SerializeField] private bool m_Interactable = true; [SerializeField] private bool m_Interactable = true;
[SerializeField] private ButtonModeType m_Mode; [SerializeField] private ButtonModeType m_Mode;
[SerializeField] private UnityEvent m_OnClick = new UnityEvent(); [SerializeField] private Button.ButtonClickedEvent m_OnClick = new Button.ButtonClickedEvent();
[SerializeField] private TransitionData m_TransitionData = new TransitionData(); [SerializeField] private TransitionData m_TransitionData = new TransitionData();
@ -80,7 +84,7 @@ public class UXButton : UIBehaviour, IPointerDownHandler, IPointerUpHandler, IPo
[SerializeField] private List<ButtonSoundCell> m_ButtonUISounds = new List<ButtonSoundCell>(); [SerializeField] private List<ButtonSoundCell> m_ButtonUISounds = new List<ButtonSoundCell>();
private SelectionState m_SelectionState = SelectionState.Normal; private SelectionState m_SelectionState = SelectionState.Normal;
private bool m_ExistUI; private bool m_DownAndExistUI;
private bool m_IsDown; private bool m_IsDown;
private bool m_IsTogSelected; private bool m_IsTogSelected;
@ -97,8 +101,7 @@ public class UXButton : UIBehaviour, IPointerDownHandler, IPointerUpHandler, IPo
} }
} }
public Button.ButtonClickedEvent onClick
public UnityEvent onClick
{ {
get { return m_OnClick; } get { return m_OnClick; }
set { m_OnClick = value; } set { m_OnClick = value; }
@ -125,6 +128,7 @@ public class UXButton : UIBehaviour, IPointerDownHandler, IPointerUpHandler, IPo
void IPointerDownHandler.OnPointerDown(PointerEventData eventData) void IPointerDownHandler.OnPointerDown(PointerEventData eventData)
{ {
if (!m_Interactable) return; if (!m_Interactable) return;
if (eventData.button != PointerEventData.InputButton.Left) return;
m_IsDown = true; m_IsDown = true;
m_SelectionState = SelectionState.Pressed; m_SelectionState = SelectionState.Pressed;
UpdateVisualState(m_SelectionState, false); UpdateVisualState(m_SelectionState, false);
@ -134,11 +138,12 @@ public class UXButton : UIBehaviour, IPointerDownHandler, IPointerUpHandler, IPo
void IPointerUpHandler.OnPointerUp(PointerEventData eventData) void IPointerUpHandler.OnPointerUp(PointerEventData eventData)
{ {
if (!m_Interactable) return; if (!m_Interactable) return;
m_IsDown = false; m_IsDown = false;
if (!m_IsTogSelected) if (!m_IsTogSelected)
{ {
m_SelectionState = m_ExistUI ? SelectionState.Normal : SelectionState.Highlighted; m_SelectionState = m_DownAndExistUI ? SelectionState.Normal : SelectionState.Highlighted;
UpdateVisualState(m_SelectionState, false); UpdateVisualState(m_SelectionState, false);
} }
else else
@ -147,10 +152,8 @@ public class UXButton : UIBehaviour, IPointerDownHandler, IPointerUpHandler, IPo
UpdateVisualState(m_SelectionState, false); UpdateVisualState(m_SelectionState, false);
} }
if (!m_ExistUI) if (eventData.button != PointerEventData.InputButton.Left)
{ return;
ProcessClick();
}
PlayButtonSound(ButtonSoundType.Up); PlayButtonSound(ButtonSoundType.Up);
} }
@ -158,8 +161,10 @@ public class UXButton : UIBehaviour, IPointerDownHandler, IPointerUpHandler, IPo
void IPointerEnterHandler.OnPointerEnter(PointerEventData eventData) void IPointerEnterHandler.OnPointerEnter(PointerEventData eventData)
{ {
if (!m_Interactable || CantTouch()) return; if (!m_Interactable || CantTouch()) return;
m_SelectionState = SelectionState.Highlighted; m_SelectionState = SelectionState.Highlighted;
m_ExistUI = false; m_DownAndExistUI = false;
if (m_IsDown) return;
UpdateVisualState(m_SelectionState, false); UpdateVisualState(m_SelectionState, false);
PlayButtonSound(ButtonSoundType.Enter); PlayButtonSound(ButtonSoundType.Enter);
} }
@ -169,7 +174,7 @@ public class UXButton : UIBehaviour, IPointerDownHandler, IPointerUpHandler, IPo
if (!m_Interactable) return; if (!m_Interactable) return;
if (m_IsDown) if (m_IsDown)
{ {
m_ExistUI = true; m_DownAndExistUI = true;
return; return;
} }
@ -202,6 +207,7 @@ public class UXButton : UIBehaviour, IPointerDownHandler, IPointerUpHandler, IPo
{ {
if (m_Mode == ButtonModeType.Normal) if (m_Mode == ButtonModeType.Normal)
{ {
UISystemProfilerApi.AddMarker("Button.onClick", this);
onClick?.Invoke(); onClick?.Invoke();
} }
else else
@ -318,4 +324,12 @@ public class UXButton : UIBehaviour, IPointerDownHandler, IPointerUpHandler, IPo
return null; return null;
} }
public void OnPointerClick(PointerEventData eventData)
{
if (eventData.button != PointerEventData.InputButton.Left)
return;
PlayButtonSound(ButtonSoundType.Click);
ProcessClick();
}
} }