From 7b4feec0f0eb8a7af67063eda3c7a0d8d8bc2b5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=80=9D=E6=B5=B7?= <1464576565@qq.com> Date: Wed, 18 Mar 2026 16:01:18 +0800 Subject: [PATCH] rmv --- Runtime/UXComponent/Button/UXButton.cs | 3 +-- Runtime/UXComponent/Group/UXGroup.cs | 21 +++------------ Runtime/UXComponent/Group/UXToggle.cs | 18 ++----------- .../UXComponent/Hotkey/HotkeyBindComponent.cs | 1 - .../Hotkey/UXHotkeyRegisterManager.cs | 26 ------------------- Runtime/UXComponent/Image/UXImage.cs | 1 - 6 files changed, 6 insertions(+), 64 deletions(-) diff --git a/Runtime/UXComponent/Button/UXButton.cs b/Runtime/UXComponent/Button/UXButton.cs index 6a27d96..59760aa 100644 --- a/Runtime/UXComponent/Button/UXButton.cs +++ b/Runtime/UXComponent/Button/UXButton.cs @@ -76,8 +76,7 @@ namespace UnityEngine.UI { Press(); PlayAudio(clickAudioClip); - // if we get set disabled during the press - // don't run the coroutine. + if (!IsActive() || !IsInteractable()) return; diff --git a/Runtime/UXComponent/Group/UXGroup.cs b/Runtime/UXComponent/Group/UXGroup.cs index 78c1d7c..07ba2d3 100644 --- a/Runtime/UXComponent/Group/UXGroup.cs +++ b/Runtime/UXComponent/Group/UXGroup.cs @@ -21,7 +21,6 @@ namespace UnityEngine.UI [SerializeField] private List m_Toggles = new List(); - // 新增:默认选中的 Toggle(可在 Inspector 设置) [SerializeField] private UXToggle m_DefaultToggle; @@ -76,7 +75,6 @@ namespace UnityEngine.UI if (m_Toggles.Contains(toggle)) m_Toggles.Remove(toggle); - // 如果被移除的正好是默认选项,则清空默认项 if (m_DefaultToggle == toggle) { m_DefaultToggle = null; @@ -91,32 +89,27 @@ namespace UnityEngine.UI if (!m_Toggles.Contains(toggle)) m_Toggles.Add(toggle); - // 当组内已有其他开启项,并且不允许 all-off 时, - // 如果新加入的 toggle 本身为 on,则需要把它关闭以维持单选。 + if (!allowSwitchOff) { - // 如果已经有一个 active 的 toggle(且不是刚加入的这个),并且刚加入的 toggle isOn 为 true,则关闭刚加入的 toggle + var firstActive = GetFirstActiveToggle(); if (firstActive != null && firstActive != toggle && toggle.isOn) { - // 我们使用不触发回调的方式避免编辑时产生不必要的事件调用 toggle.SetIsOnWithoutNotify(false); } else if (firstActive == null) { - // 没有任何 active 且不允许 all-off:如果 group 指定了 defaultToggle,优先选中它(但仅当 default 在本组内且可交互) if (m_DefaultToggle != null && m_Toggles.Contains(m_DefaultToggle)) { var dt = m_DefaultToggle; if (dt != null && dt != toggle) { - // 确保默认项被选中(editor/runtime 都适用) dt.isOn = true; NotifyToggleOn(dt); } else if (dt == toggle) { - // 新加入项就是默认项,确保它为 on toggle.isOn = true; NotifyToggleOn(toggle); } @@ -125,22 +118,19 @@ namespace UnityEngine.UI } } - // 新增:判断组里是否包含某 toggle(用于运行时/编辑器避免重复注册) + public bool ContainsToggle(UXToggle toggle) { return m_Toggles != null && m_Toggles.Contains(toggle); } - // Ensure list consistency: clean nulls, and make sure every toggle in this list actually references this group. public void EnsureValidState() { if (m_Toggles == null) m_Toggles = new List(); - // Remove null references first m_Toggles.RemoveAll(x => x == null); - // 如果不允许 all-off,优先尝试选中 defaultToggle,否则选中第一个。 if (!allowSwitchOff && !AnyTogglesOn() && m_Toggles.Count != 0) { UXToggle toSelect = null; @@ -164,7 +154,6 @@ namespace UnityEngine.UI if (activeToggles.Count() > 1) { - // 如果 defaultToggle 是开启的,优先保留它 UXToggle firstActive = GetFirstActiveToggle(); foreach (UXToggle toggle in activeToggles) @@ -178,8 +167,6 @@ namespace UnityEngine.UI } } - // Synchronize each toggle's group reference to this group if necessary, - // but avoid causing re-ordering in cases where it's already consistent. for (int i = 0; i < m_Toggles.Count; i++) { var t = m_Toggles[i]; @@ -188,7 +175,6 @@ namespace UnityEngine.UI if (t.group != this) { - // 使用 setter 会触发必要的注册/注销逻辑 t.group = this; } } @@ -206,7 +192,6 @@ namespace UnityEngine.UI public UXToggle GetFirstActiveToggle() { - // 优先返回 defaultToggle(如果它处于 on 且在组内) if (m_DefaultToggle != null && m_Toggles.Contains(m_DefaultToggle) && m_DefaultToggle.isOn) return m_DefaultToggle; diff --git a/Runtime/UXComponent/Group/UXToggle.cs b/Runtime/UXComponent/Group/UXToggle.cs index 0a5bf96..d163f0e 100644 --- a/Runtime/UXComponent/Group/UXToggle.cs +++ b/Runtime/UXComponent/Group/UXToggle.cs @@ -101,10 +101,9 @@ namespace UnityEngine.UI base.OnDidApplyAnimationProperties(); } - // Centralized group setter logic. + private void SetToggleGroup(UXGroup newGroup, bool setMemberValue) { - // 如果组没有改变,仍然需要确保组里包含此 toggle(修复编辑器中批量拖拽只注册最后一项的问题) if (m_Group == newGroup) { if (setMemberValue) @@ -115,21 +114,18 @@ namespace UnityEngine.UI newGroup.RegisterToggle(this); } - // 尝试同步组状态,确保编辑器批量赋值时能稳定显示 if (newGroup != null) newGroup.EnsureValidState(); return; } - // 从旧组注销(如果存在) if (m_Group != null) m_Group.UnregisterToggle(this); if (setMemberValue) m_Group = newGroup; - // 注册到新组(不再强依赖 IsActive(),以保证编辑器批量赋值时也能正确注册) if (newGroup != null) { if (!newGroup.ContainsToggle(this)) @@ -137,11 +133,9 @@ namespace UnityEngine.UI newGroup.RegisterToggle(this); } - // 如果正在 on,通知组(维持单选逻辑) if (isOn) newGroup.NotifyToggleOn(this); - // 同步组的内部状态,确保 Inspector 列表正确显示 newGroup.EnsureValidState(); } } @@ -157,19 +151,14 @@ namespace UnityEngine.UI Set(value, false); } -// 在 UXToggle 类内(建议放在类底部较靠近 Set 和 PlayEffect 的位置)加入: - -// 覆盖 DoStateTransition,保证 isOn 时视觉上总是 Selected(除非 Disabled) protected override void DoStateTransition(Selectable.SelectionState state, bool instant) { - // 如果被禁用,照常显示 Disabled if (state == Selectable.SelectionState.Disabled) { base.DoStateTransition(state, instant); return; } - // 当 isOn 为 true 时,总是以 Selected 的样式渲染(但不改变 EventSystem 的真实 selection) if (m_IsOn) state = Selectable.SelectionState.Selected; @@ -199,11 +188,8 @@ namespace UnityEngine.UI onValueChanged.Invoke(m_IsOn); } - // 触发选择态视觉刷新(当 isOn 为 true 显示 Selected,false 时回到 normal/hover/... 的计算结果) - // instant 参数:如果 ToggleTransition 是 None 我们使用 instant,为保持和原来 PlayEffect 一致。 bool instant = (toggleTransition == Toggle.ToggleTransition.None); - // 传入的 state:当 isOn 为 true,DoStateTransition 会将其替换为 Selected; - // 当 isOn 为 false,使用 currentSelectionState 以让正常的鼠标/键盘状态生效。 + var stateToApply = m_IsOn ? Selectable.SelectionState.Selected : currentSelectionState; DoStateTransition(stateToApply, instant); } diff --git a/Runtime/UXComponent/Hotkey/HotkeyBindComponent.cs b/Runtime/UXComponent/Hotkey/HotkeyBindComponent.cs index 96be405..57395de 100644 --- a/Runtime/UXComponent/Hotkey/HotkeyBindComponent.cs +++ b/Runtime/UXComponent/Hotkey/HotkeyBindComponent.cs @@ -25,7 +25,6 @@ namespace UnityEngine.UI } } - // 改成 Component[](或 MonoBehaviour[]),Unity 可以序列化 Component 引用 [SerializeField] private Component[] hotButtons; internal void BindHotKeys() diff --git a/Runtime/UXComponent/Hotkey/UXHotkeyRegisterManager.cs b/Runtime/UXComponent/Hotkey/UXHotkeyRegisterManager.cs index 5d6fe92..19fc848 100644 --- a/Runtime/UXComponent/Hotkey/UXHotkeyRegisterManager.cs +++ b/Runtime/UXComponent/Hotkey/UXHotkeyRegisterManager.cs @@ -16,7 +16,6 @@ namespace UnityEngine.UI Performed = 1 } - // 优化1: 使用struct减少GC [StructLayout(LayoutKind.Sequential, Pack = 4)] internal struct HotkeyRegistration { @@ -31,7 +30,6 @@ namespace UnityEngine.UI } } - // 优化2: 使用struct存储handler信息 [StructLayout(LayoutKind.Sequential)] internal struct HandlerInfo { @@ -47,28 +45,23 @@ namespace UnityEngine.UI internal static class UXHotkeyRegisterManager { - // 优化3: 使用数组池替代List,避免频繁扩容 private const int INITIAL_CAPACITY = 32; private const int MAX_REGISTRATIONS_PER_ACTION = 16; - // 优化4: 使用固定大小的数组池 private static HotkeyRegistration[][] _registrationPool; private static int[] _registrationCounts; private static string[] _actionIds; private static int _actionCount; private static int _actionCapacity; - // 优化5: 使用数组替代Dictionary(更快的查找) private static HandlerInfo[] _handlers; private static InputActionReference[] _actionRefs; - // 优化6: Button到ActionId的映射(使用数组索引) private static IHotkeyTrigger[] _buttons; private static int[] _buttonToActionIndex; private static int _buttonCount; private static int _buttonCapacity; - // 优化7: 缓存委托,避免每次创建 private static Action[] _cachedHandlers; private static int _cachedHandlerCount; @@ -128,7 +121,6 @@ namespace UnityEngine.UI string actionId = action.action.id.ToString(); int actionIndex = FindOrCreateActionIndex(actionId); - // 添加注册信息 ref int count = ref _registrationCounts[actionIndex]; if (count >= MAX_REGISTRATIONS_PER_ACTION) { @@ -139,11 +131,9 @@ namespace UnityEngine.UI _registrationPool[actionIndex][count] = new HotkeyRegistration(button, pressType); count++; - // 记录button映射 int buttonIndex = FindOrCreateButtonIndex(button); _buttonToActionIndex[buttonIndex] = actionIndex; - // 优化8: 只在第一次注册时创建handler if (count == 1) { Action handler = GetOrCreateHandler(actionIndex); @@ -178,7 +168,6 @@ namespace UnityEngine.UI if (actionIndex < 0) return; - // 从注册列表中移除 ref int count = ref _registrationCounts[actionIndex]; HotkeyRegistration[] registrations = _registrationPool[actionIndex]; @@ -188,12 +177,10 @@ namespace UnityEngine.UI { EHotkeyPressType pressType = registrations[i].pressType; - // 优化9: Swap-remove,避免数组移动 registrations[i] = registrations[count - 1]; registrations[count - 1] = default; count--; - // 如果是最后一个注册,清理handler if (count == 0) { ref HandlerInfo handlerInfo = ref _handlers[actionIndex]; @@ -223,12 +210,10 @@ namespace UnityEngine.UI } } - // 清理button映射 _buttons[buttonIndex] = null; _buttonToActionIndex[buttonIndex] = -1; } - // 优化10: 使用缓存的委托,避免闭包分配 [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Action GetOrCreateHandler(int actionIndex) { @@ -242,7 +227,6 @@ namespace UnityEngine.UI Array.Resize(ref _cachedHandlers, actionIndex + 1); } - // 优化11: 使用静态方法 + 参数传递,避免闭包 int capturedIndex = actionIndex; _cachedHandlers[actionIndex] = ctx => OnHotkeyTriggered(capturedIndex); return _cachedHandlers[actionIndex]; @@ -254,24 +238,20 @@ namespace UnityEngine.UI int count = _registrationCounts[actionIndex]; if (count > 0) { - // 触发最后一个注册的button(栈顶) ref HotkeyRegistration registration = ref _registrationPool[actionIndex][count - 1]; registration.button?.HotkeyActionTrigger(); } } - // 优化12: 线性查找(小数据集比Dictionary更快) [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int FindOrCreateActionIndex(string actionId) { - // 查找现有 for (int i = 0; i < _actionCount; i++) { if (_actionIds[i] == actionId) return i; } - // 创建新的 if (_actionCount >= _actionCapacity) { ExpandActionCapacity(); @@ -285,14 +265,12 @@ namespace UnityEngine.UI [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int FindOrCreateButtonIndex(IHotkeyTrigger button) { - // 查找现有 for (int i = 0; i < _buttonCount; i++) { if (ReferenceEquals(_buttons[i], button)) return i; } - // 查找空槽 for (int i = 0; i < _buttonCapacity; i++) { if (_buttons[i] == null) @@ -304,7 +282,6 @@ namespace UnityEngine.UI } } - // 扩容 if (_buttonCount >= _buttonCapacity) { ExpandButtonCapacity(); @@ -358,7 +335,6 @@ namespace UnityEngine.UI _buttonCapacity = newCapacity; } - // 优化13: 批量操作API [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void RegisterHotkeyBatch(Span buttons, InputActionReference action, EHotkeyPressType pressType) { @@ -377,7 +353,6 @@ namespace UnityEngine.UI } } - // 调试信息 #if UNITY_EDITOR public static string GetDebugInfo() { @@ -411,7 +386,6 @@ public static class UXHotkeyHotkeyExtension } } - // 优化14: 批量绑定 [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void BindHotKeyBatch(this IHotkeyTrigger[] buttons) { diff --git a/Runtime/UXComponent/Image/UXImage.cs b/Runtime/UXComponent/Image/UXImage.cs index 6c1c6c7..32b2aff 100644 --- a/Runtime/UXComponent/Image/UXImage.cs +++ b/Runtime/UXComponent/Image/UXImage.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System; using System.Linq; - namespace UnityEngine.UI {