EscapeShooter/My project/Assets/Project Files/Modules/Reward/Scripts/Runtime/UIRewardsPopup.cs

203 lines
6.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections.Generic;
using System.Linq;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace Watermelon
{
/// <summary>
/// Concrete <see cref="UIPage"/> that implements <see cref="IRewardsPopup"/> and displays a
/// grid of reward previews with fade-in/scale animations.
/// Registers itself with the <see cref="RewardsPopup"/> static facade on <see cref="Init"/> so that
/// <see cref="RewardsHolder"/> instances remain decoupled from this specific UIPage class.
/// Grid cell size adapts automatically: 300×300 for ≤6 items, 200×200 for larger sets.
/// </summary>
public class UIRewardsPopup : UIPage, IRewardsPopup
{
public override bool IsPopup => true;
[SerializeField] Image backgroundImage;
[SerializeField] RectTransform rewardsContainerTransform;
[SerializeField] GridLayoutGroup rewardsGridLayoutGroup;
[SerializeField] GameObject rewardUIPrefab;
[SerializeField] TMP_Text tapToClaimText;
[Space]
[SerializeField] Sprite defaultRewardSprite;
private SimpleCallback closeCallback;
private RewardUIData[] rewards;
private TweenCase fadeTweenCase;
private float rewardItemScale = 1f;
public override void Init()
{
RewardsPopup.Register(this);
backgroundImage.AddEvent(UnityEngine.EventSystems.EventTriggerType.PointerUp, (data) => OnCloseButtonClicked());
}
public bool Display(List<IRewardPreview> previews, SimpleCallback closeCallback)
{
this.closeCallback = closeCallback;
RewardUIData[] oldRewards = rewards;
if (!oldRewards.IsNullOrEmpty())
{
foreach (RewardUIData reward in oldRewards)
reward?.Destroy();
}
previews = previews.OrderBy(x => x.SortingOrder).ToList();
RewardUIData[] newRewards = new RewardUIData[previews.Count];
for (int i = 0; i < newRewards.Length; i++)
{
IRewardPreview preview = previews[i];
GameObject uiPrefab = preview.GetCustomUIPrefab();
if (uiPrefab == null)
uiPrefab = rewardUIPrefab;
GameObject uiObject = Instantiate(uiPrefab, rewardsContainerTransform);
uiObject.transform.ResetLocal();
UIRewardPreviewItem previewItem = uiObject.GetComponent<UIRewardPreviewItem>();
previewItem.Init(preview, defaultRewardSprite);
newRewards[i] = new RewardUIData(previewItem, preview);
}
rewards = newRewards;
UIController.ShowPage<UIRewardsPopup>();
return true;
}
protected override void OnShow()
{
float appearanceDelay = 0.1f;
if (!rewards.IsNullOrEmpty())
{
UpdateDynamicSize();
for (int i = 0; i < rewards.Length; i++)
{
RewardUIData reward = rewards[i];
UIRewardPreviewItem item = reward.Item;
item.transform.localScale = Vector3.one * rewardItemScale;
item.CanvasGroup.alpha = 0.0f;
reward.FadeTweenCase = item.CanvasGroup.DOFade(1.0f, 0.45f, appearanceDelay * (i + 1), unscaledTime: true);
reward.ScaleTweenCase = item.Image.DOScale(1.1f, 0.15f, appearanceDelay * (i + 1), unscaledTime: true).SetEasing(Ease.Type.SineOut).OnComplete(() =>
{
reward.ScaleTweenCase = item.Image.DOScale(0.95f, 0.2f, unscaledTime: true).OnComplete(() =>
{
reward.ScaleTweenCase = item.Image.DOScale(1f, 0.1f, unscaledTime: true).SetEasing(Ease.Type.SineOut);
});
});
}
}
float tapTextDelay = rewards.IsNullOrEmpty() ? 0f : appearanceDelay * rewards.Length + 0.5f;
tapToClaimText.color = tapToClaimText.color.SetAlpha(0f);
fadeTweenCase = tapToClaimText.DOFade(1f, 0.2f, tapTextDelay, unscaledTime: true).SetEasing(Ease.Type.CubicInOut);
NotifyOpened();
}
public void UpdateDynamicSize()
{
if (rewards.Length <= 6)
{
rewardsGridLayoutGroup.cellSize = new Vector2(300f, 300f);
rewardItemScale = 1f;
}
else
{
rewardsGridLayoutGroup.cellSize = new Vector2(200f, 200f);
rewardItemScale = 0.8f;
}
}
protected override void OnHide()
{
float animationDuration = 0f;
if (!rewards.IsNullOrEmpty())
{
animationDuration = 0.3f;
for (int i = 0; i < rewards.Length; i++)
{
RewardUIData reward = rewards[i];
UIRewardPreviewItem item = reward.Item;
item.CanvasGroup.alpha = 1f;
reward.FadeTweenCase = item.CanvasGroup.DOFade(0f, 0.28f, unscaledTime: true);
reward.ScaleTweenCase = item.Image.DOScaleY(1.1f, 0.05f, 0.1f, unscaledTime: true).SetEasing(Ease.Type.SineIn).OnComplete(() =>
{
reward.ScaleTweenCase = item.Image.DOScaleY(0f, 0.15f, unscaledTime: true).SetEasing(Ease.Type.SineOut);
});
}
}
Tween.DelayedCall(animationDuration, () =>
{
closeCallback?.Invoke();
NotifyClosed();
}, unscaledTime: true);
}
private void OnDestroy()
{
fadeTweenCase.KillActive();
if (!rewards.IsNullOrEmpty())
{
foreach (RewardUIData reward in rewards)
reward?.Destroy();
}
}
private void OnCloseButtonClicked()
{
UIController.HidePage(this);
}
public class RewardUIData
{
public readonly UIRewardPreviewItem Item;
public readonly IRewardPreview Preview;
public TweenCase FadeTweenCase;
public TweenCase ScaleTweenCase;
public RewardUIData(UIRewardPreviewItem item, IRewardPreview preview)
{
Item = item;
Preview = preview;
}
public void Destroy()
{
if (Item != null && Item.gameObject != null)
GameObject.Destroy(Item.gameObject);
FadeTweenCase.KillActive();
ScaleTweenCase.KillActive();
}
}
}
}