This commit is contained in:
陈思海 2025-12-17 18:44:18 +08:00
parent b54983c866
commit bac473fe0f

View File

@ -47,6 +47,9 @@ public class UXButton : UXSelectable, IButton, IPointerClickHandler, ISubmitHand
private bool m_IsNavFocused = false;
// ===== 新增:延迟撤销选择的 pending 标记,用于避免在协程尚未完成时读取过时的锁状态 =====
private bool _deferredDeselectPending = false;
#endregion
#region Properties
@ -118,6 +121,8 @@ public class UXButton : UXSelectable, IButton, IPointerClickHandler, ISubmitHand
{
if (_resetRoutine != null)
StopCoroutine(_resetRoutine);
if (_deferredDeselectRoutine != null)
StopCoroutine(_deferredDeselectRoutine);
base.OnDestroy();
}
@ -199,7 +204,9 @@ public class UXButton : UXSelectable, IButton, IPointerClickHandler, ISubmitHand
if (navigation.mode != UXNavigation.Mode.None)
{
if ((m_Mode == ButtonModeType.Normal && m_IsFocusLocked) ||
// ===== 修改:当有 deferred deselect pending 时,不应认为 focus 仍旧被 lock =====
bool focusLockedEffective = m_IsFocusLocked && !_deferredDeselectPending;
if ((m_Mode == ButtonModeType.Normal && focusLockedEffective) ||
(m_Mode == ButtonModeType.Toggle && _mTogSelected))
{
SetState(SelectionState.Selected);
@ -233,7 +240,9 @@ public class UXButton : UXSelectable, IButton, IPointerClickHandler, ISubmitHand
if (navigation.mode != UXNavigation.Mode.None)
{
if ((m_Mode == ButtonModeType.Normal && m_IsFocusLocked) ||
// ===== 修改:同上,不要在 deferred pending 时误用旧的 lock 状态 =====
bool focusLockedEffective = m_IsFocusLocked && !_deferredDeselectPending;
if ((m_Mode == ButtonModeType.Normal && focusLockedEffective) ||
(m_Mode == ButtonModeType.Toggle && _mTogSelected))
{
SetState(SelectionState.Selected);
@ -369,17 +378,24 @@ public class UXButton : UXSelectable, IButton, IPointerClickHandler, ISubmitHand
private IEnumerator DeferredDeselectCheck()
{
yield return null;
// 标记开始:表示我们在等待 EventSystem 正确更新选择(避免竞态)
_deferredDeselectPending = true;
yield return null; // 等一帧让 EventSystem 更新 currentSelectedGameObject
bool selectionIsNull = EventSystem.current == null || EventSystem.current.currentSelectedGameObject == null;
if (selectionIsNull)
{
m_IsNavFocused = false;
s_LockedButton = null;
// ===== 更安全的解锁:仅当静态锁指向自己时才清理它,避免影响其他按钮 =====
if (s_LockedButton == this)
s_LockedButton = null;
m_IsFocusLocked = false;
}
// 取消 pending 标记并清理协程引用
_deferredDeselectPending = false;
_deferredDeselectRoutine = null;
}
@ -395,6 +411,7 @@ public class UXButton : UXSelectable, IButton, IPointerClickHandler, ISubmitHand
{
StopCoroutine(_deferredDeselectRoutine);
_deferredDeselectRoutine = null;
_deferredDeselectPending = false;
}
// 延迟一帧再判断 EventSystem.current.currentSelectedGameObject避免读取到旧值