using System; using UnityEngine; using UnityEngine.UI; using TMPro; using BaseGames.Equipment; using BaseGames.Localization; namespace BaseGames.UI { /// /// 护符卡片视图组件。 /// /// 设计动机:取代 中基于 /// + 数组索引的脆弱绑定方式, /// 通过 Inspector 显式序列化引用,避免每次重建列表时的反射开销与索引漂移风险。 /// /// 用法:在卡片 Prefab 上挂载此组件并连接子节点引用, /// 仅需调用 即可完成数据 → UI 的同步。 /// [DisallowMultipleComponent] public class CharmCardView : MonoBehaviour { [Header("Visual")] [SerializeField] private Image _icon; [SerializeField] private GameObject _iconRoot; // 可选:无 icon 时整体隐藏 [Header("Text")] [SerializeField] private TMP_Text _nameText; [SerializeField] private TMP_Text _notchCostText; [SerializeField] private TMP_Text _descriptionText; [SerializeField] private TMP_Text _equipBadgeText; // 已装备角标 ("✓") [Header("Interaction")] [SerializeField] private Button _actionButton; /// /// 将护符数据绑定到视图。 /// /// 数据源。 /// 是否已装备(决定按钮行为与角标显示)。 /// 点击装备时回调(仅 = false 时使用)。 /// 点击卸下时回调(仅 = true 时使用)。 public void Bind(CharmSO charm, bool isEquipped, Action onEquip, Action onUnequip) { if (charm == null) return; // ── 图标 ──────────────────────────────────────────────────────── if (_icon != null) { _icon.sprite = charm.icon; _icon.enabled = charm.icon != null; } if (_iconRoot != null) _iconRoot.SetActive(charm.icon != null); // ── 文本(本地化容错:未找到键时回落到 charmId / 空字符串)────── if (_nameText != null) { string loc = LocalizationManager.Get(charm.displayNameKey, LocalizationTable.Items); _nameText.text = !string.IsNullOrEmpty(loc) && loc != charm.displayNameKey ? loc : charm.charmId; } if (_notchCostText != null) _notchCostText.text = charm.notchCost.ToString(); if (_descriptionText != null) { string loc = LocalizationManager.Get(charm.descriptionKey, LocalizationTable.Items); _descriptionText.text = !string.IsNullOrEmpty(loc) && loc != charm.descriptionKey ? loc : string.Empty; } if (_equipBadgeText != null) _equipBadgeText.text = isEquipped ? "✓" : string.Empty; // ── 按钮 ──────────────────────────────────────────────────────── if (_actionButton != null) { _actionButton.onClick.RemoveAllListeners(); var captured = charm; if (isEquipped) { if (onUnequip != null) _actionButton.onClick.AddListener(() => onUnequip(captured)); } else { if (onEquip != null) _actionButton.onClick.AddListener(() => onEquip(captured)); } } } } }