using UnityEngine;
using DG.Tweening;
namespace Ashwild.UI
{
///
/// Classifies how a panel affects gameplay when open, so a UI manager can apply the right
/// side effects: Default = plain menu panel, Pause = freezes the world / raises GamePaused,
/// Inventory = a local UI window where the world keeps running.
///
public enum PanelKind
{
Default,
Pause,
Inventory
}
[RequireComponent(typeof(CanvasGroup))]
public abstract class UIPanel : MonoBehaviour
{
///
/// How this panel affects gameplay while open. Overridden by panels that pause the game
/// (pause menu) or that are a local window the world keeps running under (inventory).
///
public virtual PanelKind Kind => PanelKind.Default;
[Header("Animation")]
[SerializeField] private float showDuration = 0.25f;
[SerializeField] private float hideDuration = 0.15f;
[SerializeField] private Ease showEase = Ease.OutBack;
[SerializeField] private Ease hideEase = Ease.InQuad;
[SerializeField] private float showScaleFrom = 0.9f;
protected CanvasGroup canvasGroup;
protected RectTransform rect;
private Tween currentTween;
public bool IsVisible { get; private set; }
protected virtual void Awake()
{
canvasGroup = GetComponent();
rect = GetComponent();
}
public virtual void Show()
{
currentTween?.Kill();
gameObject.SetActive(true);
IsVisible = true;
canvasGroup.alpha = 0f;
canvasGroup.interactable = true;
canvasGroup.blocksRaycasts = true;
rect.localScale = Vector3.one * showScaleFrom;
Sequence s = DOTween.Sequence();
s.Append(canvasGroup.DOFade(1f, showDuration));
s.Join(rect.DOScale(1f, showDuration).SetEase(showEase));
currentTween = s;
}
public virtual void Hide()
{
if (!IsVisible) return;
currentTween?.Kill();
IsVisible = false;
canvasGroup.interactable = false;
canvasGroup.blocksRaycasts = false;
currentTween = canvasGroup.DOFade(0f, hideDuration)
.SetEase(hideEase)
.OnComplete(() => gameObject.SetActive(false));
}
public virtual void HideInstant()
{
currentTween?.Kill();
IsVisible = false;
canvasGroup.alpha = 0f;
canvasGroup.interactable = false;
canvasGroup.blocksRaycasts = false;
rect.localScale = Vector3.one;
gameObject.SetActive(false);
}
}
}