From 1723b4d893b66ab0b33e224c542075e142a87dd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=80=9D=E6=B5=B7?= <1464576565@qq.com> Date: Mon, 15 Dec 2025 20:54:23 +0800 Subject: [PATCH] fix --- Runtime/UXComponent/Button/UXButton.cs | 42 ++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/Runtime/UXComponent/Button/UXButton.cs b/Runtime/UXComponent/Button/UXButton.cs index cf536cc..8bcbc7e 100644 --- a/Runtime/UXComponent/Button/UXButton.cs +++ b/Runtime/UXComponent/Button/UXButton.cs @@ -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); } /// @@ -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())