using UnityEngine; using UnityEngine.UI; using TMPro; using BaseGames.Core.Events; namespace BaseGames.UI { /// /// 工具栏 HUD(架构 09_ProgressionModule §7.5)。 /// 显示 2 个工具槽的图标 + 剩余次数 + 冷却遮罩。 /// public class ToolHUD : MonoBehaviour { [SerializeField] private ToolSlotUI[] _slots; // 2 个 ToolSlotUI 组件 [SerializeField] private BaseGames.Equipment.ToolSlotManager _slotManager; [SerializeField] private ToolUsedEventChannelSO _onToolUsed; private readonly CompositeDisposable _subs = new(); private void OnEnable() { _onToolUsed?.Subscribe(RefreshSlot).AddTo(_subs); } private void OnDisable() { _subs.Clear(); } private void RefreshSlot(ToolUsedPayload payload) { int i = payload.SlotIndex; if (_slots == null || i < 0 || i >= _slots.Length) return; _slots[i].Refresh( _slotManager.GetTool(i), _slotManager.GetRemainingUses(i), _slotManager.GetCooldownRatio(i)); } private void Update() { if (_slots == null || _slotManager == null) return; for (int i = 0; i < _slots.Length; i++) _slots[i].SetCooldownFill(_slotManager.GetCooldownRatio(i)); } } /// /// 单个工具槽 UI:图标 + 剩余次数文本 + 冷却遮罩 Image(FillAmount)。 /// public class ToolSlotUI : MonoBehaviour { [SerializeField] private Image _icon; [SerializeField] private TMP_Text _usesText; [SerializeField] private Image _cooldownMask; // type = Filled, Image Type = Filled public void Refresh(BaseGames.Equipment.ToolSO tool, int remainingUses, float cooldownRatio) { if (_icon != null) _icon.sprite = tool != null ? tool.icon : null; if (_usesText != null) _usesText.text = remainingUses < 0 ? "∞" : remainingUses.ToString(); SetCooldownFill(cooldownRatio); } public void SetCooldownFill(float ratio) { if (_cooldownMask != null) _cooldownMask.fillAmount = Mathf.Clamp01(ratio); } } }