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; [SerializeField] private CanvasGroup canvasGroup; [Header("Animation Settings")] [SerializeField] private float cardRevealDelay = 0.5f; [SerializeField] private float cardMoveToBackpackDelay = 1.0f; [SerializeField] private Transform backpackTargetTransform; [SerializeField] private AudioSource cardRevealSound; [SerializeField] private AudioSource rareCardSound; [SerializeField] private ParticleSystem cardRevealParticles; [SerializeField] private ParticleSystem rareCardParticles; // State tracking private enum OpeningState { BoosterReady, CardsRevealing, CardsRevealed, MovingToBackpack, Completed } private OpeningState _currentState = OpeningState.BoosterReady; private List _revealedCards = new List(); private CardSystemManager _cardManager; private Coroutine _revealCoroutine; private Coroutine _moveToBackpackCoroutine; 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); } // Make sure we have a CanvasGroup for transitions if (canvasGroup == null) canvasGroup = GetComponent(); if (canvasGroup == null) canvasGroup = gameObject.AddComponent(); } private void OnDestroy() { // Clean up button listeners if (openBoosterButton != null) { openBoosterButton.onClick.RemoveListener(OnOpenBoosterClicked); } if (continueButton != null) { continueButton.onClick.RemoveListener(OnContinueClicked); } // Stop any running coroutines if (_revealCoroutine != null) StopCoroutine(_revealCoroutine); if (_moveToBackpackCoroutine != null) StopCoroutine(_moveToBackpackCoroutine); } /// /// 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) { if (card != null && card.gameObject != null) 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; _currentState = OpeningState.CardsRevealing; // 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) { // Animate the booster pack opening Tween.LocalScale(boosterPackObject.transform, Vector3.zero, 0.3f, 0f, Tween.EaseInBack, Tween.LoopType.None, null, () => { boosterPackObject.SetActive(false); }); } if (openBoosterButton != null) { openBoosterButton.gameObject.SetActive(false); } // Start revealing cards _revealCoroutine = 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(); // Play appropriate sound and particles based on rarity if (cardData.Rarity >= CardRarity.Rare) { // Play rare card sound if (rareCardSound != null) { rareCardSound.Play(); } // Play rare card particles if (rareCardParticles != null) { rareCardParticles.transform.position = cardObj.transform.position; rareCardParticles.Play(); } } else { // Play regular card sound if (cardRevealSound != null) { cardRevealSound.Play(); } // Play regular particles if (cardRevealParticles != null) { cardRevealParticles.transform.position = cardObj.transform.position; cardRevealParticles.Play(); } } // 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); // Animate button appearance continueButton.transform.localScale = Vector3.zero; Tween.LocalScale(continueButton.transform, Vector3.one, 0.3f, 0f, Tween.EaseOutBack); } } /// /// Handles click on the continue button after cards are revealed /// private void OnContinueClicked() { if (_currentState != OpeningState.CardsRevealed) return; _currentState = OpeningState.MovingToBackpack; if (continueButton != null) { continueButton.gameObject.SetActive(false); } // Start moving cards to backpack animation _moveToBackpackCoroutine = StartCoroutine(MoveCardsToBackpack()); } /// /// Animates cards moving to the backpack /// private IEnumerator MoveCardsToBackpack() { // If no backpack target, use a default position (lower-right corner) Vector3 targetPosition = (backpackTargetTransform != null) ? backpackTargetTransform.position : new Vector3(Screen.width * 0.9f, Screen.height * 0.1f, 0f); // Move each card to backpack with animation foreach (var cardUI in _revealedCards) { if (cardUI != null) { // Call card's move to backpack animation cardUI.OnMoveToBackpackAnimation(); // Animate movement to backpack Tween.Position(cardUI.transform, targetPosition, 0.5f, 0f, Tween.EaseInBack); Tween.LocalScale(cardUI.transform, Vector3.zero, 0.5f, 0f, Tween.EaseInBack); // Wait for delay between cards yield return new WaitForSeconds(0.2f); } } // Wait for final animation yield return new WaitForSeconds(0.5f); // Update state to completed _currentState = OpeningState.Completed; // Return to previous page UIPageController.Instance.PopPage(); } // Override for transition animations protected override void DoTransitionIn(System.Action onComplete) { // Simple fade in animation if (canvasGroup != null) { canvasGroup.alpha = 0f; Tween.Value(0f, 1f, (value) => canvasGroup.alpha = value, transitionDuration, 0f, Tween.EaseInOut, Tween.LoopType.None, null, onComplete); } else { onComplete?.Invoke(); } } protected override void DoTransitionOut(System.Action onComplete) { // Simple fade out animation if (canvasGroup != null) { Tween.Value(canvasGroup.alpha, 0f, (value) => canvasGroup.alpha = value, transitionDuration, 0f, Tween.EaseInOut, Tween.LoopType.None, null, onComplete); } else { onComplete?.Invoke(); } } } }