using PrimeTween; using UnityEngine; using UnityEngine.UI; namespace BriarQueen.UI.Menus.Components { public class SaveSlotHighlight : MonoBehaviour { [Header("Lines")] [SerializeField] private RectTransform _topLine; [SerializeField] private RectTransform _bottomLine; [Header("Colours")] [SerializeField] private Color _hoverColour = new(0.65f, 0.10f, 0.10f, 0.5f); [SerializeField] private Color _selectedColour = new(0.65f, 0.10f, 0.10f, 1.0f); [Header("Tween")] [SerializeField] private float _duration = 0.25f; [SerializeField] private Ease _ease = Ease.OutQuint; [SerializeField] private bool _useUnscaledTime = true; private Image _topImage; private Image _bottomImage; private Tween _topTween; private Tween _bottomTween; private Tween _topColourTween; private Tween _bottomColourTween; private bool _isSelected; private bool _isHovered; private void Awake() { if (_topLine != null) _topImage = _topLine.GetComponent(); if (_bottomLine != null) _bottomImage = _bottomLine.GetComponent(); // Start fully scaled out on X SetScaleImmediate(0f); SetColourImmediate(Color.clear); } private void OnDestroy() { _topTween.Stop(); _bottomTween.Stop(); _topColourTween.Stop(); _bottomColourTween.Stop(); } // ── Public API ──────────────────────────────────────────────── public void SetSelected(bool selected) { _isSelected = selected; RefreshState(); } public void SetSelectedImmediate(bool selected) { _isSelected = selected; StopAllTweens(); var (scale, colour) = ResolveTargetState(); SetScaleImmediate(scale); SetColourImmediate(colour); } public void SetHovered(bool hovered) { _isHovered = hovered; RefreshState(); } // ── Internal ────────────────────────────────────────────────── private void RefreshState() { var (scale, colour) = ResolveTargetState(); TweenToScale(scale); TweenToColour(colour); } private (float scale, Color colour) ResolveTargetState() { if (_isSelected) return (1f, _selectedColour); if (_isHovered) return (1f, _hoverColour); return (0f, Color.clear); } private void TweenToScale(float target) { _topTween.Stop(); _bottomTween.Stop(); var currentScale = _topLine != null ? _topLine.localScale.x : 0f; if (_topLine != null) { _topTween = Tween.ScaleX( _topLine, currentScale, target, _duration, _ease, useUnscaledTime: _useUnscaledTime); } if (_bottomLine != null) { _bottomTween = Tween.ScaleX( _bottomLine, currentScale, target, _duration, _ease, useUnscaledTime: _useUnscaledTime); } } private void TweenToColour(Color target) { _topColourTween.Stop(); _bottomColourTween.Stop(); if (_topImage != null) { _topColourTween = Tween.Color( _topImage, _topImage.color, target, _duration, _ease, useUnscaledTime: _useUnscaledTime); } if (_bottomImage != null) { _bottomColourTween = Tween.Color( _bottomImage, _bottomImage.color, target, _duration, _ease, useUnscaledTime: _useUnscaledTime); } } private void SetScaleImmediate(float scaleX) { if (_topLine != null) _topLine.localScale = new Vector3(scaleX, 1f, 1f); if (_bottomLine != null) _bottomLine.localScale = new Vector3(scaleX, 1f, 1f); } private void SetColourImmediate(Color colour) { if (_topImage != null) _topImage.color = colour; if (_bottomImage != null) _bottomImage.color = colour; } private void StopAllTweens() { _topTween.Stop(); _bottomTween.Stop(); _topColourTween.Stop(); _bottomColourTween.Stop(); } } }