diff --git a/Runtime/UXComponent/Button/UXButton.cs b/Runtime/UXComponent/Button/UXButton.cs index 8666d87..0ce1188 100644 --- a/Runtime/UXComponent/Button/UXButton.cs +++ b/Runtime/UXComponent/Button/UXButton.cs @@ -374,21 +374,43 @@ public class UXButton : UXSelectable, IButton, IPointerClickHandler, ISubmitHand // 等一帧,保证 EventSystem 更新 currentSelectedGameObject yield return null; - bool selectionIsNull = EventSystem.current == null || EventSystem.current.currentSelectedGameObject == null; + // 当前选中对象(可能为 null) + var currentSelected = EventSystem.current != null ? EventSystem.current.currentSelectedGameObject : null; - if (selectionIsNull) + if (currentSelected == null) { - // 统一走封装入口清理锁 + // 没有任何选中对象:清理锁 SetLockedButton(null); - - // 额外保证本实例的本地标志被清掉(以防极端顺序仍然残留) m_IsFocusLocked = false; } + else + { + // 如果有选中对象,检查它是否属于一个 UXButton(可能是子对象) + var selectedBtn = currentSelected.GetComponentInParent(); + + if (selectedBtn == null) + { + // 新选中对象不是 UXButton 的组成部分:清理锁 + SetLockedButton(null); + m_IsFocusLocked = false; + } + else if (selectedBtn != this) + { + // 新选中对象属于另一个 UXButton:把锁转给那个按钮 + // (即便目标的 OnSelect 也可能会做这件事,这里直接转能避免时序问题) + SetLockedButton(selectedBtn); + } + else + { + // selectedBtn == this:焦点仍然在自己上,不需要清理 + } + } _deferredDeselectRoutine = null; } + public override void OnDeselect(BaseEventData eventData) { base.OnDeselect(eventData);