This commit is contained in:
陈思海 2025-12-15 20:54:23 +08:00
parent ed5bbeb2ac
commit 1723b4d893

View File

@ -37,6 +37,7 @@ public class UXButton : UXSelectable, IButton, IPointerClickHandler, ISubmitHand
private bool m_HasExitedWhileDown;
private bool _mTogSelected;
private Coroutine _resetRoutine;
private Coroutine _deferredDeselectRoutine;
private WaitForSeconds _waitFadeDuration;
// 静态锁(用于 normal 模式点击后的“保持 Selected”并能转移
@ -365,21 +366,43 @@ public class UXButton : UXSelectable, IButton, IPointerClickHandler, ISubmitHand
}
}
private IEnumerator DeferredDeselectCheck()
{
// 等一帧,保证 EventSystem 更新 currentSelectedGameObject
yield return null;
bool selectionIsNull = EventSystem.current == null || EventSystem.current.currentSelectedGameObject == null;
if (selectionIsNull)
{
// 统一走封装入口清理锁
SetLockedButton(null);
// 额外保证本实例的本地标志被清掉(以防极端顺序仍然残留)
m_IsFocusLocked = false;
}
_deferredDeselectRoutine = null;
}
public override void OnDeselect(BaseEventData eventData)
{
base.OnDeselect(eventData);
m_IsNavFocused = false;
bool selectionIsNull = EventSystem.current == null || EventSystem.current.currentSelectedGameObject == null;
if (selectionIsNull)
// 停掉上一次的延迟检查(若有)
if (_deferredDeselectRoutine != null)
{
if (s_LockedButton == this)
s_LockedButton = null;
m_IsFocusLocked = false;
StopCoroutine(_deferredDeselectRoutine);
_deferredDeselectRoutine = null;
}
// Toggle 模式:如果逻辑上已选中则保持 Selected否则恢复 Normal
// 延迟一帧再判断 EventSystem.current.currentSelectedGameObject避免读取到旧值
_deferredDeselectRoutine = StartCoroutine(DeferredDeselectCheck());
// 视觉状态先按原逻辑处理(立即更新视觉),协程会确保锁状态在正确时刻被清理
if (m_Mode == ButtonModeType.Toggle)
{
if (_mTogSelected)
@ -511,6 +534,7 @@ public class UXButton : UXSelectable, IButton, IPointerClickHandler, ISubmitHand
private void SetState(SelectionState state)
{
ForceSetState(state);
ApplyVisualState(state, true);
}
/// <summary>
@ -534,6 +558,12 @@ public class UXButton : UXSelectable, IButton, IPointerClickHandler, ISubmitHand
#endregion
protected override void OnSetProperty()
{
base.OnSetProperty();
ApplyVisualState(m_SelectionState, true);
}
public void Focus()
{
if (!IsInteractable())