2025-10-10 14:31:51 +02:00
|
|
|
|
using System.Collections;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using AppleHills.Data.CardSystem;
|
2025-10-14 15:53:58 +02:00
|
|
|
|
using Core;
|
2025-10-14 14:57:50 +02:00
|
|
|
|
using Data.CardSystem;
|
2025-10-10 14:31:51 +02:00
|
|
|
|
using Pixelplacement;
|
2025-10-20 10:29:22 +02:00
|
|
|
|
using TMPro;
|
2025-10-10 14:31:51 +02:00
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
using UnityEngine.UI;
|
|
|
|
|
|
|
|
|
|
|
|
namespace AppleHills.UI.CardSystem
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// UI page for opening booster packs and displaying the cards obtained.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public class BoosterOpeningPage : UIPage
|
|
|
|
|
|
{
|
|
|
|
|
|
[Header("UI Elements")]
|
|
|
|
|
|
[SerializeField] private GameObject boosterPackObject;
|
2025-10-20 10:29:22 +02:00
|
|
|
|
[SerializeField] private RectTransform cardRevealContainer; // This should have a HorizontalLayoutGroup component
|
2025-10-10 14:31:51 +02:00
|
|
|
|
[SerializeField] private GameObject cardPrefab;
|
2025-10-20 10:29:22 +02:00
|
|
|
|
[SerializeField] private GameObject cardBackPrefab;
|
2025-10-10 14:31:51 +02:00
|
|
|
|
[SerializeField] private Button openBoosterButton;
|
|
|
|
|
|
[SerializeField] private Button continueButton;
|
2025-10-15 09:22:13 +02:00
|
|
|
|
[SerializeField] private CanvasGroup canvasGroup;
|
2025-10-10 14:31:51 +02:00
|
|
|
|
|
2025-10-20 10:29:22 +02:00
|
|
|
|
[Header("Navigation")]
|
|
|
|
|
|
[SerializeField] private Button backButton;
|
|
|
|
|
|
|
2025-10-10 14:31:51 +02:00
|
|
|
|
[Header("Animation Settings")]
|
2025-10-20 10:29:22 +02:00
|
|
|
|
[SerializeField] private float cardRevealDelay = 0.3f;
|
|
|
|
|
|
[SerializeField] private float cardMoveToBackpackDelay = 0.8f;
|
|
|
|
|
|
[SerializeField] private float flipAnimationDuration = 0.5f;
|
2025-10-10 14:31:51 +02:00
|
|
|
|
|
|
|
|
|
|
// State tracking
|
|
|
|
|
|
private enum OpeningState
|
|
|
|
|
|
{
|
|
|
|
|
|
BoosterReady,
|
2025-10-20 10:29:22 +02:00
|
|
|
|
CardBacksVisible,
|
2025-10-15 09:22:13 +02:00
|
|
|
|
CardsRevealing,
|
2025-10-10 14:31:51 +02:00
|
|
|
|
CardsRevealed,
|
2025-10-15 09:22:13 +02:00
|
|
|
|
MovingToBackpack,
|
2025-10-10 14:31:51 +02:00
|
|
|
|
Completed
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private OpeningState _currentState = OpeningState.BoosterReady;
|
|
|
|
|
|
private List<CardUIElement> _revealedCards = new List<CardUIElement>();
|
2025-10-20 10:29:22 +02:00
|
|
|
|
private List<GameObject> _cardBacks = new List<GameObject>();
|
|
|
|
|
|
private List<CardData> _boosterCards = new List<CardData>();
|
|
|
|
|
|
private int _revealedCardCount = 0;
|
2025-10-10 14:31:51 +02:00
|
|
|
|
private CardSystemManager _cardManager;
|
2025-10-20 10:29:22 +02:00
|
|
|
|
private CardAlbumUI _cardAlbumUI;
|
2025-10-15 09:22:13 +02:00
|
|
|
|
private Coroutine _moveToBackpackCoroutine;
|
2025-10-10 14:31:51 +02:00
|
|
|
|
|
|
|
|
|
|
private void Awake()
|
|
|
|
|
|
{
|
|
|
|
|
|
_cardManager = CardSystemManager.Instance;
|
2025-10-20 10:29:22 +02:00
|
|
|
|
_cardAlbumUI = FindObjectOfType<CardAlbumUI>();
|
2025-10-10 14:31:51 +02:00
|
|
|
|
|
|
|
|
|
|
// Set up button listeners
|
|
|
|
|
|
if (openBoosterButton != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
openBoosterButton.onClick.AddListener(OnOpenBoosterClicked);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (continueButton != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
continueButton.onClick.AddListener(OnContinueClicked);
|
|
|
|
|
|
continueButton.gameObject.SetActive(false);
|
|
|
|
|
|
}
|
2025-10-15 09:22:13 +02:00
|
|
|
|
|
2025-10-20 10:29:22 +02:00
|
|
|
|
// Set up back button
|
|
|
|
|
|
if (backButton != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
backButton.onClick.AddListener(OnBackButtonClicked);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-15 09:22:13 +02:00
|
|
|
|
// Make sure we have a CanvasGroup for transitions
|
|
|
|
|
|
if (canvasGroup == null)
|
|
|
|
|
|
canvasGroup = GetComponent<CanvasGroup>();
|
|
|
|
|
|
if (canvasGroup == null)
|
|
|
|
|
|
canvasGroup = gameObject.AddComponent<CanvasGroup>();
|
2025-10-10 14:31:51 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void OnDestroy()
|
|
|
|
|
|
{
|
|
|
|
|
|
// Clean up button listeners
|
|
|
|
|
|
if (openBoosterButton != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
openBoosterButton.onClick.RemoveListener(OnOpenBoosterClicked);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (continueButton != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
continueButton.onClick.RemoveListener(OnContinueClicked);
|
|
|
|
|
|
}
|
2025-10-15 09:22:13 +02:00
|
|
|
|
|
2025-10-20 10:29:22 +02:00
|
|
|
|
if (backButton != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
backButton.onClick.RemoveListener(OnBackButtonClicked);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-15 09:22:13 +02:00
|
|
|
|
// Stop any running coroutines
|
|
|
|
|
|
if (_moveToBackpackCoroutine != null)
|
|
|
|
|
|
StopCoroutine(_moveToBackpackCoroutine);
|
2025-10-10 14:31:51 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-20 10:29:22 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Handles click on the back button
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private void OnBackButtonClicked()
|
|
|
|
|
|
{
|
|
|
|
|
|
// Don't allow going back during animations or card reveals
|
|
|
|
|
|
if (_currentState == OpeningState.CardsRevealing ||
|
|
|
|
|
|
_currentState == OpeningState.MovingToBackpack)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Use the UIPageController to go back to the previous page
|
|
|
|
|
|
UIPageController pageController = UIPageController.Instance;
|
|
|
|
|
|
if (pageController != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
pageController.PopPage();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-10 14:31:51 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Resets the page to its initial state when it becomes active
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public override void TransitionIn()
|
|
|
|
|
|
{
|
|
|
|
|
|
base.TransitionIn();
|
|
|
|
|
|
|
|
|
|
|
|
ResetState();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Resets the state of the booster opening process
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private void ResetState()
|
|
|
|
|
|
{
|
|
|
|
|
|
// Clear any previously revealed cards
|
|
|
|
|
|
foreach (var card in _revealedCards)
|
|
|
|
|
|
{
|
2025-10-15 09:22:13 +02:00
|
|
|
|
if (card != null && card.gameObject != null)
|
|
|
|
|
|
Destroy(card.gameObject);
|
2025-10-10 14:31:51 +02:00
|
|
|
|
}
|
|
|
|
|
|
_revealedCards.Clear();
|
|
|
|
|
|
|
2025-10-20 10:29:22 +02:00
|
|
|
|
// Clear card backs
|
|
|
|
|
|
foreach (var cardBack in _cardBacks)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (cardBack != null)
|
|
|
|
|
|
Destroy(cardBack);
|
|
|
|
|
|
}
|
|
|
|
|
|
_cardBacks.Clear();
|
|
|
|
|
|
|
2025-10-10 14:31:51 +02:00
|
|
|
|
// Reset state
|
|
|
|
|
|
_currentState = OpeningState.BoosterReady;
|
2025-10-20 10:29:22 +02:00
|
|
|
|
_revealedCardCount = 0;
|
2025-10-10 14:31:51 +02:00
|
|
|
|
|
2025-10-20 10:29:22 +02:00
|
|
|
|
// Show booster pack, show open button, hide continue button
|
2025-10-10 14:31:51 +02:00
|
|
|
|
if (boosterPackObject != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
boosterPackObject.SetActive(true);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (openBoosterButton != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
openBoosterButton.gameObject.SetActive(true);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (continueButton != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
continueButton.gameObject.SetActive(false);
|
|
|
|
|
|
}
|
2025-10-20 10:29:22 +02:00
|
|
|
|
|
|
|
|
|
|
// Make back button visible
|
|
|
|
|
|
if (backButton != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
backButton.gameObject.SetActive(true);
|
|
|
|
|
|
}
|
2025-10-10 14:31:51 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Handles click on the booster pack to open it
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private void OnOpenBoosterClicked()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_currentState != OpeningState.BoosterReady) return;
|
|
|
|
|
|
|
2025-10-20 10:29:22 +02:00
|
|
|
|
_currentState = OpeningState.CardBacksVisible;
|
2025-10-15 09:22:13 +02:00
|
|
|
|
|
2025-10-10 14:31:51 +02:00
|
|
|
|
// Open the booster pack and get the cards
|
2025-10-20 10:29:22 +02:00
|
|
|
|
_boosterCards = _cardManager.OpenBoosterPack();
|
2025-10-10 14:31:51 +02:00
|
|
|
|
|
2025-10-20 10:29:22 +02:00
|
|
|
|
if (_boosterCards.Count > 0)
|
2025-10-10 14:31:51 +02:00
|
|
|
|
{
|
|
|
|
|
|
// Hide the booster pack and open button
|
|
|
|
|
|
if (boosterPackObject != null)
|
|
|
|
|
|
{
|
2025-10-15 09:22:13 +02:00
|
|
|
|
// Animate the booster pack opening
|
|
|
|
|
|
Tween.LocalScale(boosterPackObject.transform, Vector3.zero, 0.3f, 0f, Tween.EaseInBack, Tween.LoopType.None, null, () => {
|
|
|
|
|
|
boosterPackObject.SetActive(false);
|
|
|
|
|
|
});
|
2025-10-10 14:31:51 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (openBoosterButton != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
openBoosterButton.gameObject.SetActive(false);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-20 10:29:22 +02:00
|
|
|
|
// Show card backs first
|
|
|
|
|
|
StartCoroutine(ShowCardBacks());
|
2025-10-10 14:31:51 +02:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2025-10-14 15:53:58 +02:00
|
|
|
|
Logging.Warning("[BoosterOpeningPage] No cards were obtained from the booster pack.");
|
2025-10-10 14:31:51 +02:00
|
|
|
|
UIPageController.Instance.PopPage();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-10-20 10:29:22 +02:00
|
|
|
|
/// Shows card backs in the reveal positions
|
2025-10-10 14:31:51 +02:00
|
|
|
|
/// </summary>
|
2025-10-20 10:29:22 +02:00
|
|
|
|
private IEnumerator ShowCardBacks()
|
2025-10-10 14:31:51 +02:00
|
|
|
|
{
|
2025-10-20 10:29:22 +02:00
|
|
|
|
// Wait a short delay before showing card backs
|
2025-10-10 14:31:51 +02:00
|
|
|
|
yield return new WaitForSeconds(0.5f);
|
|
|
|
|
|
|
2025-10-20 10:29:22 +02:00
|
|
|
|
// Create card backs for each position (usually 3)
|
|
|
|
|
|
for (int i = 0; i < Mathf.Min(_boosterCards.Count, cardRevealContainer.childCount); i++)
|
2025-10-10 14:31:51 +02:00
|
|
|
|
{
|
2025-10-20 10:29:22 +02:00
|
|
|
|
if (cardBackPrefab == null || cardRevealContainer.GetChild(i) == null) continue;
|
|
|
|
|
|
|
|
|
|
|
|
// Instantiate card back object at the correct position
|
|
|
|
|
|
GameObject cardBackObj = Instantiate(cardBackPrefab, cardRevealContainer.GetChild(i));
|
|
|
|
|
|
cardBackObj.transform.localPosition = Vector3.zero;
|
|
|
|
|
|
_cardBacks.Add(cardBackObj);
|
2025-10-10 14:31:51 +02:00
|
|
|
|
|
2025-10-20 10:29:22 +02:00
|
|
|
|
// Store the index for later reference when clicked
|
|
|
|
|
|
int cardIndex = i;
|
|
|
|
|
|
|
|
|
|
|
|
// Add click handler to the card back
|
|
|
|
|
|
Button cardBackButton = cardBackObj.GetComponent<Button>();
|
|
|
|
|
|
if (cardBackButton == null)
|
2025-10-10 14:31:51 +02:00
|
|
|
|
{
|
2025-10-20 10:29:22 +02:00
|
|
|
|
cardBackButton = cardBackObj.AddComponent<Button>();
|
2025-10-10 14:31:51 +02:00
|
|
|
|
}
|
2025-10-20 10:29:22 +02:00
|
|
|
|
|
|
|
|
|
|
// Configure the button
|
|
|
|
|
|
cardBackButton.onClick.AddListener(() => OnCardBackClicked(cardIndex));
|
|
|
|
|
|
|
|
|
|
|
|
// Set initial scale to zero for animation
|
|
|
|
|
|
cardBackObj.transform.localScale = Vector3.zero;
|
|
|
|
|
|
|
|
|
|
|
|
// Play reveal animation using Pixelplacement.Tween
|
|
|
|
|
|
Tween.LocalScale(cardBackObj.transform, Vector3.one, 0.5f, 0f, Tween.EaseOutBack);
|
|
|
|
|
|
|
|
|
|
|
|
// Wait for animation delay
|
|
|
|
|
|
yield return new WaitForSeconds(cardRevealDelay);
|
2025-10-10 14:31:51 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-20 10:29:22 +02:00
|
|
|
|
// Update state
|
|
|
|
|
|
_currentState = OpeningState.CardBacksVisible;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Handles click on a card back to reveal the card
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private void OnCardBackClicked(int cardIndex)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Only respond to clicks when in the appropriate state
|
|
|
|
|
|
if (_currentState != OpeningState.CardBacksVisible) return;
|
|
|
|
|
|
|
|
|
|
|
|
// Ensure the index is valid
|
|
|
|
|
|
if (cardIndex < 0 || cardIndex >= _boosterCards.Count || cardIndex >= _cardBacks.Count) return;
|
|
|
|
|
|
|
|
|
|
|
|
// Get the card data and card back
|
|
|
|
|
|
CardData cardData = _boosterCards[cardIndex];
|
|
|
|
|
|
GameObject cardBack = _cardBacks[cardIndex];
|
|
|
|
|
|
|
|
|
|
|
|
// Start the reveal animation for this specific card
|
|
|
|
|
|
StartCoroutine(RevealCard(cardIndex, cardData, cardBack));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Reveals an individual card with animation
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private IEnumerator RevealCard(int cardIndex, CardData cardData, GameObject cardBack)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (cardBack == null || cardRevealContainer.GetChild(cardIndex) == null) yield break;
|
|
|
|
|
|
|
|
|
|
|
|
// Start flip animation
|
|
|
|
|
|
Transform cardBackTransform = cardBack.transform;
|
|
|
|
|
|
|
|
|
|
|
|
// Step 1: Flip the card 90 degrees (showing the edge)
|
|
|
|
|
|
Tween.LocalRotation(cardBackTransform, new Vector3(0, 90, 0), flipAnimationDuration * 0.5f, 0);
|
|
|
|
|
|
|
|
|
|
|
|
// Wait for half the flip duration
|
|
|
|
|
|
yield return new WaitForSeconds(flipAnimationDuration * 0.5f);
|
|
|
|
|
|
|
|
|
|
|
|
// Step 2: Remove the card back and create the actual card
|
|
|
|
|
|
Destroy(cardBack);
|
|
|
|
|
|
_cardBacks[cardIndex] = null;
|
|
|
|
|
|
|
|
|
|
|
|
// Create the actual card at the same position
|
|
|
|
|
|
GameObject cardObj = Instantiate(cardPrefab, cardRevealContainer.GetChild(cardIndex));
|
|
|
|
|
|
cardObj.transform.localPosition = Vector3.zero;
|
|
|
|
|
|
cardObj.transform.localRotation = Quaternion.Euler(0, 90, 0); // Start at 90 degrees
|
|
|
|
|
|
|
|
|
|
|
|
// Set up the card data
|
|
|
|
|
|
CardUIElement cardUI = cardObj.GetComponent<CardUIElement>();
|
|
|
|
|
|
if (cardUI != null)
|
2025-10-10 14:31:51 +02:00
|
|
|
|
{
|
2025-10-20 10:29:22 +02:00
|
|
|
|
cardUI.SetupCard(cardData);
|
|
|
|
|
|
_revealedCards.Add(cardUI);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Step 3: Complete the flip animation
|
|
|
|
|
|
Tween.LocalRotation(cardObj.transform, Vector3.zero, flipAnimationDuration * 0.5f, 0);
|
|
|
|
|
|
|
|
|
|
|
|
// Increment the revealed card count
|
|
|
|
|
|
_revealedCardCount++;
|
|
|
|
|
|
|
|
|
|
|
|
// If all cards have been revealed, show the continue button
|
|
|
|
|
|
if (_revealedCardCount >= _boosterCards.Count)
|
|
|
|
|
|
{
|
|
|
|
|
|
_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);
|
|
|
|
|
|
}
|
2025-10-10 14:31:51 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Handles click on the continue button after cards are revealed
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private void OnContinueClicked()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_currentState != OpeningState.CardsRevealed) return;
|
|
|
|
|
|
|
2025-10-15 09:22:13 +02:00
|
|
|
|
_currentState = OpeningState.MovingToBackpack;
|
|
|
|
|
|
|
|
|
|
|
|
if (continueButton != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
continueButton.gameObject.SetActive(false);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-10 14:31:51 +02:00
|
|
|
|
// Start moving cards to backpack animation
|
2025-10-15 09:22:13 +02:00
|
|
|
|
_moveToBackpackCoroutine = StartCoroutine(MoveCardsToBackpack());
|
2025-10-10 14:31:51 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Animates cards moving to the backpack
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private IEnumerator MoveCardsToBackpack()
|
|
|
|
|
|
{
|
2025-10-20 10:29:22 +02:00
|
|
|
|
// Use the backpackIcon from CardAlbumUI as the target
|
|
|
|
|
|
Vector3 targetPosition;
|
|
|
|
|
|
|
|
|
|
|
|
if (_cardAlbumUI != null && _cardAlbumUI.transform.Find("BackpackIcon") != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Get the world position of the backpack icon
|
|
|
|
|
|
targetPosition = _cardAlbumUI.transform.Find("BackpackIcon").position;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// Fallback to a default position (lower-right corner)
|
|
|
|
|
|
targetPosition = new Vector3(Screen.width * 0.9f, Screen.height * 0.1f, 0f);
|
|
|
|
|
|
Logging.Warning("[BoosterOpeningPage] Couldn't find backpack icon, using default position.");
|
|
|
|
|
|
}
|
2025-10-10 14:31:51 +02:00
|
|
|
|
|
2025-10-15 09:22:13 +02:00
|
|
|
|
// Move each card to backpack with animation
|
|
|
|
|
|
foreach (var cardUI in _revealedCards)
|
2025-10-10 14:31:51 +02:00
|
|
|
|
{
|
2025-10-15 09:22:13 +02:00
|
|
|
|
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);
|
|
|
|
|
|
}
|
2025-10-10 14:31:51 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-15 09:22:13 +02:00
|
|
|
|
// Wait for final animation
|
|
|
|
|
|
yield return new WaitForSeconds(0.5f);
|
2025-10-10 14:31:51 +02:00
|
|
|
|
|
2025-10-15 09:22:13 +02:00
|
|
|
|
// Update state to completed
|
2025-10-10 14:31:51 +02:00
|
|
|
|
_currentState = OpeningState.Completed;
|
2025-10-15 09:22:13 +02:00
|
|
|
|
|
|
|
|
|
|
// Return to previous page
|
2025-10-10 14:31:51 +02:00
|
|
|
|
UIPageController.Instance.PopPage();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-15 09:22:13 +02:00
|
|
|
|
// Override for transition animations
|
2025-10-10 14:31:51 +02:00
|
|
|
|
protected override void DoTransitionIn(System.Action onComplete)
|
|
|
|
|
|
{
|
2025-10-15 09:22:13 +02:00
|
|
|
|
// Simple fade in animation
|
|
|
|
|
|
if (canvasGroup != null)
|
2025-10-10 14:31:51 +02:00
|
|
|
|
{
|
2025-10-15 09:22:13 +02:00
|
|
|
|
canvasGroup.alpha = 0f;
|
|
|
|
|
|
Tween.Value(0f, 1f, (value) => canvasGroup.alpha = value, transitionDuration, 0f, Tween.EaseInOut, Tween.LoopType.None, null, onComplete);
|
2025-10-10 14:31:51 +02:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
onComplete?.Invoke();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
protected override void DoTransitionOut(System.Action onComplete)
|
|
|
|
|
|
{
|
2025-10-15 09:22:13 +02:00
|
|
|
|
// Simple fade out animation
|
2025-10-10 14:31:51 +02:00
|
|
|
|
if (canvasGroup != null)
|
|
|
|
|
|
{
|
2025-10-15 09:22:13 +02:00
|
|
|
|
Tween.Value(canvasGroup.alpha, 0f, (value) => canvasGroup.alpha = value, transitionDuration, 0f, Tween.EaseInOut, Tween.LoopType.None, null, onComplete);
|
2025-10-10 14:31:51 +02:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
onComplete?.Invoke();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|