using UnityEngine; using UnityEngine.UI; using TMPro; namespace BaseGames.UI.Theme { /// /// 将 中的视觉令牌应用到当前 GameObject 及其子节点。 /// /// 用法: /// 1. 在 Prefab 根节点挂载此组件并指定 ; /// 2. 在每个需要主题化的子节点添加 组件指定角色; /// 3. 会被 自动调用一次, /// 也可在主题切换后手动调用。 /// /// 性能:使用 一次性收集, /// 仅在 Enable / 显式刷新时执行;运行时无每帧成本。 /// [DisallowMultipleComponent] public class UIThemeApplier : MonoBehaviour { [SerializeField] private UIThemeSO _theme; [Tooltip("启用时自动应用一次。运行时切换主题可手动调用 Apply()。")] [SerializeField] private bool _applyOnEnable = true; private void OnEnable() { if (_applyOnEnable) Apply(); } /// 用当前 覆盖子节点上所有 标记。 public void Apply() { if (_theme == null) return; var roles = GetComponentsInChildren(includeInactive: true); for (int i = 0; i < roles.Length; i++) ApplyRole(roles[i], _theme); } /// 运行时切换主题。 public void SetTheme(UIThemeSO theme) { _theme = theme; Apply(); } private static void ApplyRole(UIThemeRole role, UIThemeSO theme) { if (role == null) return; switch (role.Kind) { case UIThemeRoleKind.Graphic_Primary: SetGraphicColor(role, theme.Primary); break; case UIThemeRoleKind.Graphic_Secondary: SetGraphicColor(role, theme.Secondary); break; case UIThemeRoleKind.Graphic_Accent: SetGraphicColor(role, theme.Accent); break; case UIThemeRoleKind.Graphic_Background: SetGraphicColor(role, theme.Background); break; case UIThemeRoleKind.Graphic_Success: SetGraphicColor(role, theme.Success); break; case UIThemeRoleKind.Graphic_Warning: SetGraphicColor(role, theme.Warning); break; case UIThemeRoleKind.Graphic_Danger: SetGraphicColor(role, theme.Danger); break; case UIThemeRoleKind.Text_Primary: SetTextStyle(role, theme.TextPrimary, theme.BodyFont, theme.BodyFontSize); break; case UIThemeRoleKind.Text_Secondary: SetTextStyle(role, theme.TextSecondary, theme.BodyFont, theme.SmallFontSize); break; case UIThemeRoleKind.Text_Header: SetTextStyle(role, theme.TextPrimary, theme.HeaderFont, theme.HeaderFontSize); break; case UIThemeRoleKind.Text_Disabled: SetTextStyle(role, theme.TextDisabled, theme.BodyFont, theme.BodyFontSize); break; case UIThemeRoleKind.Button: SetButtonColors(role, theme); break; } } private static void SetGraphicColor(UIThemeRole role, Color c) { var g = role.GetComponent(); if (g != null) g.color = c; } private static void SetTextStyle(UIThemeRole role, Color c, TMP_FontAsset font, float size) { var tmp = role.GetComponent(); if (tmp != null) { tmp.color = c; if (font != null) tmp.font = font; if (role.OverrideFontSize) tmp.fontSize = size; } } private static void SetButtonColors(UIThemeRole role, UIThemeSO theme) { var btn = role.GetComponent