using System.Collections; using System.Collections.Generic; using AppleHills.Data.CardSystem; using Core; using Data.CardSystem; using Pixelplacement; using UnityEngine; using UnityEngine.UI; namespace AppleHills.UI.CardSystem { /// /// UI page for opening booster packs and displaying the cards obtained. /// public class BoosterOpeningPage : UIPage { [Header("UI Elements")] [SerializeField] private GameObject boosterPackObject; [SerializeField] private Transform cardRevealTransform; [SerializeField] private GameObject cardPrefab; [SerializeField] private Button openBoosterButton; [SerializeField] private Button continueButton; [Header("Animation Settings")] [SerializeField] private float cardRevealDelay = 0.5f; [SerializeField] private float cardMoveToBackpackDelay = 1.0f; // State tracking private enum OpeningState { BoosterReady, CardsRevealed, Completed } private OpeningState _currentState = OpeningState.BoosterReady; private List _revealedCards = new List(); private CardSystemManager _cardManager; private void Awake() { _cardManager = CardSystemManager.Instance; // Set up button listeners if (openBoosterButton != null) { openBoosterButton.onClick.AddListener(OnOpenBoosterClicked); } if (continueButton != null) { continueButton.onClick.AddListener(OnContinueClicked); continueButton.gameObject.SetActive(false); } } private void OnDestroy() { // Clean up button listeners if (openBoosterButton != null) { openBoosterButton.onClick.RemoveListener(OnOpenBoosterClicked); } if (continueButton != null) { continueButton.onClick.RemoveListener(OnContinueClicked); } } /// /// Resets the page to its initial state when it becomes active /// public override void TransitionIn() { base.TransitionIn(); ResetState(); } /// /// Resets the state of the booster opening process /// private void ResetState() { // Clear any previously revealed cards foreach (var card in _revealedCards) { Destroy(card.gameObject); } _revealedCards.Clear(); // Reset state _currentState = OpeningState.BoosterReady; // Show booster pack, hide continue button if (boosterPackObject != null) { boosterPackObject.SetActive(true); } if (openBoosterButton != null) { openBoosterButton.gameObject.SetActive(true); } if (continueButton != null) { continueButton.gameObject.SetActive(false); } } /// /// Handles click on the booster pack to open it /// private void OnOpenBoosterClicked() { if (_currentState != OpeningState.BoosterReady) return; // Open the booster pack and get the cards List newCards = _cardManager.OpenBoosterPack(); if (newCards.Count > 0) { // Hide the booster pack and open button if (boosterPackObject != null) { boosterPackObject.SetActive(false); } if (openBoosterButton != null) { openBoosterButton.gameObject.SetActive(false); } // Start revealing cards StartCoroutine(RevealCards(newCards)); } else { Logging.Warning("[BoosterOpeningPage] No cards were obtained from the booster pack."); UIPageController.Instance.PopPage(); } } /// /// Reveals cards one by one with animation /// private IEnumerator RevealCards(List cards) { // Wait a short delay before revealing cards yield return new WaitForSeconds(0.5f); // Reveal each card foreach (var cardData in cards) { // Instantiate card UI element GameObject cardObj = Instantiate(cardPrefab, cardRevealTransform); CardUIElement cardUI = cardObj.GetComponent(); if (cardUI != null) { // Set up the card data cardUI.SetupCard(cardData); _revealedCards.Add(cardUI); // Set initial scale to zero for animation cardObj.transform.localScale = Vector3.zero; // Play reveal animation using Pixelplacement.Tween Tween.LocalScale(cardObj.transform, Vector3.one, 0.5f, 0f, Tween.EaseOutBack); // Call card's show animation cardUI.OnShowAnimation(); // Wait for animation delay yield return new WaitForSeconds(cardRevealDelay); } } // Update state and show continue button _currentState = OpeningState.CardsRevealed; if (continueButton != null) { continueButton.gameObject.SetActive(true); } } /// /// Handles click on the continue button after cards are revealed /// private void OnContinueClicked() { if (_currentState != OpeningState.CardsRevealed) return; // Start moving cards to backpack animation StartCoroutine(MoveCardsToBackpack()); } /// /// Animates cards moving to the backpack /// private IEnumerator MoveCardsToBackpack() { // Hide continue button if (continueButton != null) { continueButton.gameObject.SetActive(false); } // Get corner position for backpack (bottom left) Vector3 cornerPosition = new Vector3(-Screen.width/2 + 50, -Screen.height/2 + 50, 0); // Animate each card moving to the backpack foreach (var card in _revealedCards) { // Play move to backpack animation using Pixelplacement.Tween Tween.Position(card.transform, cornerPosition, 0.5f, 0f, Tween.EaseInBack); Tween.LocalScale(card.transform, Vector3.zero, 0.5f, 0f, Tween.EaseInBack); // Call card's move to backpack animation card.OnMoveToBackpackAnimation(); // Wait for animation delay yield return new WaitForSeconds(cardMoveToBackpackDelay); } // Wait a moment before completing yield return new WaitForSeconds(0.3f); // Complete the process and return to previous page _currentState = OpeningState.Completed; UIPageController.Instance.PopPage(); } /// /// Override for transition in animation using Pixelplacement.Tween /// protected override void DoTransitionIn(System.Action onComplete) { // Scale in animation for the booster pack if (boosterPackObject != null) { boosterPackObject.transform.localScale = Vector3.zero; Tween.LocalScale(boosterPackObject.transform, Vector3.one, transitionDuration, 0f, Tween.EaseOutBack, Tween.LoopType.None, null, onComplete); } else { onComplete?.Invoke(); } } /// /// Override for transition out animation using Pixelplacement.Tween /// protected override void DoTransitionOut(System.Action onComplete) { // Fade out animation using a CanvasGroup if available CanvasGroup canvasGroup = GetComponent(); if (canvasGroup != null) { Tween.Value(canvasGroup.alpha, 0f, (value) => canvasGroup.alpha = value, transitionDuration, 0f, Tween.EaseInOut, Tween.LoopType.None, null, onComplete); } else { onComplete?.Invoke(); } } } }