using UnityEngine; using UnityEngine.UI; using TMPro; using DG.Tweening; namespace Ashwild.Inventory { /// /// The fixed description panel shown beside the inventory — a pure view. When the pointer /// enters a filled slot the inventory manager hands it an and /// it fades its CanvasGroup in, drawing the icon, name, description and (for uses-tracked items) /// the duration bar. It never reads ItemData or the inventory itself; it renders what it is given. /// [DisallowMultipleComponent] public class HoverDescriptionUI : MonoBehaviour { #region Serialized Fields [Header("References")] [SerializeField] private CanvasGroup canvasGroup; [SerializeField] private Image iconImage; [SerializeField] private TextMeshProUGUI nameText; [SerializeField] private TextMeshProUGUI descriptionText; [Header("Duration Bar")] [Tooltip("Root object of the duration/uses bar — shown only for items that track uses.")] [SerializeField] private GameObject durationBarRoot; [Tooltip("Filled image whose fillAmount maps to the remaining uses (Image Type = Filled).")] [SerializeField] private Image durationBarFill; [Tooltip("Label drawn over the bar, e.g. \"3 / 5\".")] [SerializeField] private TextMeshProUGUI durationText; [Header("Animation")] [SerializeField] private float fadeDuration = 0.15f; #endregion #region State private Tweener fadeTween; #endregion #region Unity Lifecycle /// /// Starts hidden so the panel only appears once a slot is actually hovered. /// private void Awake() => SetHidden(); /// /// Kills the fade tween so it never targets the CanvasGroup after teardown. /// private void OnDestroy() => fadeTween?.Kill(); #endregion #region Public API /// /// Draws the payload and fades the panel in. Called by the inventory manager on hover enter. /// public void Show(ItemDescriptionView view) { if (iconImage != null) { iconImage.sprite = view.Icon; iconImage.enabled = view.Icon != null; } if (nameText != null) nameText.text = view.Name; if (descriptionText != null) descriptionText.text = view.Description; if (durationBarRoot != null) durationBarRoot.SetActive(view.HasDuration); if (view.HasDuration) { if (durationBarFill != null) durationBarFill.fillAmount = view.DurationFill; if (durationText != null) durationText.text = view.DurationText; } fadeTween?.Kill(); fadeTween = canvasGroup.DOFade(1f, fadeDuration).SetUpdate(true); } /// /// Fades the panel out via its CanvasGroup only — the GameObject stays active so it can be /// shown again instantly. Called on hover exit / inventory close. /// public void Hide() { fadeTween?.Kill(); fadeTween = canvasGroup.DOFade(0f, fadeDuration).SetUpdate(true); } #endregion #region Internal Helpers /// /// Instantly parks the panel invisible via the CanvasGroup, without deactivating it. /// private void SetHidden() => canvasGroup.alpha = 0f; #endregion } }