Kind of working booster packs
This commit is contained in:
@@ -17,9 +17,8 @@ namespace AppleHills.UI.CardSystem
|
||||
{
|
||||
[Header("UI Elements")]
|
||||
[SerializeField] private GameObject boosterPackObject;
|
||||
[SerializeField] private RectTransform cardRevealContainer; // This should have a HorizontalLayoutGroup component
|
||||
[SerializeField] private RectTransform cardRevealContainer; // This should have a HorizontalLayoutGroup component with pre-populated card backs
|
||||
[SerializeField] private GameObject cardPrefab;
|
||||
[SerializeField] private GameObject cardBackPrefab;
|
||||
[SerializeField] private Button openBoosterButton;
|
||||
[SerializeField] private Button continueButton;
|
||||
[SerializeField] private CanvasGroup canvasGroup;
|
||||
@@ -45,7 +44,7 @@ namespace AppleHills.UI.CardSystem
|
||||
|
||||
private OpeningState _currentState = OpeningState.BoosterReady;
|
||||
private List<CardUIElement> _revealedCards = new List<CardUIElement>();
|
||||
private List<GameObject> _cardBacks = new List<GameObject>();
|
||||
private List<Button> _cardBackButtons = new List<Button>();
|
||||
private List<CardData> _boosterCards = new List<CardData>();
|
||||
private int _revealedCardCount = 0;
|
||||
private CardSystemManager _cardManager;
|
||||
@@ -80,6 +79,47 @@ namespace AppleHills.UI.CardSystem
|
||||
canvasGroup = GetComponent<CanvasGroup>();
|
||||
if (canvasGroup == null)
|
||||
canvasGroup = gameObject.AddComponent<CanvasGroup>();
|
||||
|
||||
// Cache card back buttons from container
|
||||
CacheCardBackButtons();
|
||||
|
||||
// Initially hide all card backs
|
||||
HideAllCardBacks();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cache all card back buttons from the container
|
||||
/// </summary>
|
||||
private void CacheCardBackButtons()
|
||||
{
|
||||
_cardBackButtons.Clear();
|
||||
|
||||
if (cardRevealContainer != null)
|
||||
{
|
||||
// Get all buttons in the container (these are our card backs)
|
||||
Button[] buttonsInContainer = cardRevealContainer.GetComponentsInChildren<Button>(true);
|
||||
_cardBackButtons.AddRange(buttonsInContainer);
|
||||
|
||||
Debug.Log($"[BoosterOpeningPage] Found {_cardBackButtons.Count} card back buttons in container");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("[BoosterOpeningPage] Card reveal container is null, can't find card backs!");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hides all card backs in the container
|
||||
/// </summary>
|
||||
private void HideAllCardBacks()
|
||||
{
|
||||
foreach (var cardBack in _cardBackButtons)
|
||||
{
|
||||
if (cardBack != null && cardBack.gameObject != null)
|
||||
{
|
||||
cardBack.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
@@ -148,22 +188,31 @@ namespace AppleHills.UI.CardSystem
|
||||
}
|
||||
_revealedCards.Clear();
|
||||
|
||||
// Clear card backs
|
||||
foreach (var cardBack in _cardBacks)
|
||||
// Re-cache card backs in case they changed
|
||||
CacheCardBackButtons();
|
||||
|
||||
// Reset all card backs - both visibility and scale
|
||||
foreach (var cardBack in _cardBackButtons)
|
||||
{
|
||||
if (cardBack != null)
|
||||
Destroy(cardBack);
|
||||
if (cardBack != null && cardBack.gameObject != null)
|
||||
{
|
||||
cardBack.gameObject.SetActive(false);
|
||||
cardBack.transform.localScale = Vector3.one; // Reset scale
|
||||
cardBack.transform.localRotation = Quaternion.identity; // Reset rotation
|
||||
}
|
||||
}
|
||||
_cardBacks.Clear();
|
||||
|
||||
// Reset state
|
||||
_currentState = OpeningState.BoosterReady;
|
||||
_revealedCardCount = 0;
|
||||
_boosterCards.Clear();
|
||||
|
||||
// Show booster pack, show open button, hide continue button
|
||||
if (boosterPackObject != null)
|
||||
{
|
||||
boosterPackObject.SetActive(true);
|
||||
boosterPackObject.transform.localScale = Vector3.one; // Reset scale
|
||||
boosterPackObject.transform.localRotation = Quaternion.identity; // Reset rotation
|
||||
}
|
||||
|
||||
if (openBoosterButton != null)
|
||||
@@ -174,6 +223,7 @@ namespace AppleHills.UI.CardSystem
|
||||
if (continueButton != null)
|
||||
{
|
||||
continueButton.gameObject.SetActive(false);
|
||||
continueButton.transform.localScale = Vector3.one; // Reset scale
|
||||
}
|
||||
|
||||
// Make back button visible
|
||||
@@ -181,6 +231,8 @@ namespace AppleHills.UI.CardSystem
|
||||
{
|
||||
backButton.gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
Debug.Log("[BoosterOpeningPage] State reset complete, all scales and rotations reset to defaults");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -229,32 +281,46 @@ namespace AppleHills.UI.CardSystem
|
||||
// Wait a short delay before showing card backs
|
||||
yield return new WaitForSeconds(0.5f);
|
||||
|
||||
// Create card backs for each position (usually 3)
|
||||
for (int i = 0; i < Mathf.Min(_boosterCards.Count, cardRevealContainer.childCount); i++)
|
||||
// Check if we have proper container setup
|
||||
if (cardRevealContainer == null)
|
||||
{
|
||||
if (cardBackPrefab == null || cardRevealContainer.GetChild(i) == null) continue;
|
||||
Debug.LogError("[BoosterOpeningPage] Card reveal container is null!");
|
||||
yield break;
|
||||
}
|
||||
|
||||
// Check if we found any card backs
|
||||
if (_cardBackButtons.Count == 0)
|
||||
{
|
||||
Debug.LogError("[BoosterOpeningPage] No card back buttons found in container!");
|
||||
yield break;
|
||||
}
|
||||
|
||||
// Determine how many cards to show based on the booster cards and available card backs
|
||||
int cardsToShow = Mathf.Min(_boosterCards.Count, _cardBackButtons.Count);
|
||||
|
||||
// Activate and animate the card backs
|
||||
for (int i = 0; i < cardsToShow; i++)
|
||||
{
|
||||
Button cardBack = _cardBackButtons[i];
|
||||
if (cardBack == 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);
|
||||
GameObject cardBackObj = cardBack.gameObject;
|
||||
|
||||
// Ensure the card back is active
|
||||
cardBackObj.SetActive(true);
|
||||
|
||||
// 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)
|
||||
{
|
||||
cardBackButton = cardBackObj.AddComponent<Button>();
|
||||
}
|
||||
|
||||
// Configure the button
|
||||
cardBackButton.onClick.AddListener(() => OnCardBackClicked(cardIndex));
|
||||
cardBack.onClick.RemoveAllListeners(); // Clear any previous listeners
|
||||
cardBack.onClick.AddListener(() => OnCardBackClicked(cardIndex));
|
||||
|
||||
// Set initial scale to zero for animation
|
||||
cardBackObj.transform.localScale = Vector3.zero;
|
||||
|
||||
Debug.Log($"[BoosterOpeningPage] Card back {i} activated");
|
||||
|
||||
// Play reveal animation using Pixelplacement.Tween
|
||||
Tween.LocalScale(cardBackObj.transform, Vector3.one, 0.5f, 0f, Tween.EaseOutBack);
|
||||
|
||||
@@ -264,6 +330,7 @@ namespace AppleHills.UI.CardSystem
|
||||
|
||||
// Update state
|
||||
_currentState = OpeningState.CardBacksVisible;
|
||||
Debug.Log($"[BoosterOpeningPage] All {cardsToShow} card backs should now be visible");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -271,140 +338,213 @@ namespace AppleHills.UI.CardSystem
|
||||
/// </summary>
|
||||
private void OnCardBackClicked(int cardIndex)
|
||||
{
|
||||
Logging.Debug($"[BoosterOpeningPage] Card back clicked at index {cardIndex}");
|
||||
|
||||
// Only respond to clicks when in the appropriate state
|
||||
if (_currentState != OpeningState.CardBacksVisible) return;
|
||||
if (_currentState != OpeningState.CardBacksVisible)
|
||||
{
|
||||
Logging.Warning($"[BoosterOpeningPage] Card clicked in wrong state: {_currentState}");
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure the index is valid
|
||||
if (cardIndex < 0 || cardIndex >= _boosterCards.Count || cardIndex >= _cardBacks.Count) return;
|
||||
if (cardIndex < 0 || cardIndex >= _boosterCards.Count || cardIndex >= _cardBackButtons.Count)
|
||||
{
|
||||
Debug.LogError($"[BoosterOpeningPage] Invalid card index: {cardIndex}");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the card data and card back
|
||||
CardData cardData = _boosterCards[cardIndex];
|
||||
GameObject cardBack = _cardBacks[cardIndex];
|
||||
Button cardBack = _cardBackButtons[cardIndex];
|
||||
|
||||
// Start the reveal animation for this specific card
|
||||
StartCoroutine(RevealCard(cardIndex, cardData, cardBack));
|
||||
StartCoroutine(RevealCard(cardIndex, cardData, cardBack.gameObject));
|
||||
}
|
||||
|
||||
|
||||
/// <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;
|
||||
|
||||
if (cardBack == 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)
|
||||
|
||||
// Step 2: Hide the card back and show the actual card
|
||||
cardBack.SetActive(false);
|
||||
|
||||
// Instantiate the card prefab at the same position
|
||||
if (cardPrefab != null)
|
||||
{
|
||||
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)
|
||||
// Instantiate the card in the same parent as the card back and at the same position
|
||||
GameObject cardObj = Instantiate(cardPrefab, cardBack.transform.parent);
|
||||
cardObj.transform.SetSiblingIndex(cardBackTransform.GetSiblingIndex()); // Keep the same order in hierarchy
|
||||
cardObj.transform.position = cardBackTransform.position; // Same world position
|
||||
|
||||
// Set initial rotation to continue the flip animation
|
||||
cardObj.transform.localRotation = Quaternion.Euler(0, 90, 0);
|
||||
|
||||
// Configure the card UI with the card data
|
||||
CardUIElement cardUI = cardObj.GetComponent<CardUIElement>();
|
||||
if (cardUI != null)
|
||||
{
|
||||
continueButton.gameObject.SetActive(true);
|
||||
|
||||
// Animate button appearance
|
||||
continueButton.transform.localScale = Vector3.zero;
|
||||
Tween.LocalScale(continueButton.transform, Vector3.one, 0.3f, 0f, Tween.EaseOutBack);
|
||||
cardUI.SetupCard(cardData);
|
||||
_revealedCards.Add(cardUI);
|
||||
|
||||
// Play special effects based on card rarity
|
||||
PlayRevealEffect(cardObj, cardData.Rarity);
|
||||
}
|
||||
|
||||
// Step 3: Finish the flip animation (from 90 degrees to 0)
|
||||
Tween.LocalRotation(cardObj.transform, Vector3.zero, flipAnimationDuration * 0.5f, 0);
|
||||
|
||||
// Increment counter of revealed cards
|
||||
_revealedCardCount++;
|
||||
|
||||
// Update state if all cards are revealed
|
||||
if (_revealedCardCount >= _boosterCards.Count)
|
||||
{
|
||||
_currentState = OpeningState.CardsRevealed;
|
||||
|
||||
// Show continue button after a short delay
|
||||
StartCoroutine(ShowContinueButton());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Handles click on the continue button after cards are revealed
|
||||
/// Plays reveal effect for a card based on its rarity
|
||||
/// </summary>
|
||||
private void PlayRevealEffect(GameObject cardObject, CardRarity rarity)
|
||||
{
|
||||
// Add visual effect based on rarity
|
||||
if (rarity >= CardRarity.Rare)
|
||||
{
|
||||
// For rare cards and above, add a particle effect
|
||||
var particleSystem = cardObject.GetComponentInChildren<ParticleSystem>();
|
||||
if (particleSystem != null)
|
||||
{
|
||||
particleSystem.Play();
|
||||
}
|
||||
|
||||
// Scale up and down for emphasis
|
||||
Transform cardTransform = cardObject.transform;
|
||||
Vector3 originalScale = cardTransform.localScale;
|
||||
|
||||
// Sequence: Scale up slightly, then back to normal
|
||||
Tween.LocalScale(cardTransform, originalScale * 1.2f, 0.2f, 0.1f, Tween.EaseOutBack);
|
||||
Tween.LocalScale(cardTransform, originalScale, 0.15f, 0.3f, Tween.EaseIn);
|
||||
|
||||
// Play sound effect based on rarity (if available)
|
||||
// This would require audio source components to be set up
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows the continue button after all cards are revealed
|
||||
/// </summary>
|
||||
private IEnumerator ShowContinueButton()
|
||||
{
|
||||
// Wait for a moment to let the user see all cards
|
||||
yield return new WaitForSeconds(1.0f);
|
||||
|
||||
if (continueButton != null)
|
||||
{
|
||||
// Show the continue button with a nice animation
|
||||
continueButton.gameObject.SetActive(true);
|
||||
continueButton.transform.localScale = Vector3.zero;
|
||||
|
||||
Tween.LocalScale(continueButton.transform, Vector3.one, 0.3f, 0f, Tween.EaseOutBack);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles click on the continue button
|
||||
/// </summary>
|
||||
private void OnContinueClicked()
|
||||
{
|
||||
if (_currentState != OpeningState.CardsRevealed) return;
|
||||
|
||||
|
||||
_currentState = OpeningState.MovingToBackpack;
|
||||
|
||||
|
||||
// Hide continue button
|
||||
if (continueButton != null)
|
||||
{
|
||||
continueButton.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
// Start moving cards to backpack animation
|
||||
|
||||
// Hide back button during transition
|
||||
if (backButton != null)
|
||||
{
|
||||
backButton.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
// Start animation to move cards to backpack
|
||||
_moveToBackpackCoroutine = StartCoroutine(MoveCardsToBackpack());
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Animates cards moving to the backpack
|
||||
/// Animates cards moving to the backpack icon
|
||||
/// </summary>
|
||||
private IEnumerator MoveCardsToBackpack()
|
||||
{
|
||||
// Use the backpackIcon from CardAlbumUI as the target
|
||||
Vector3 targetPosition;
|
||||
|
||||
if (_cardAlbumUI != null && _cardAlbumUI.transform.Find("BackpackIcon") != null)
|
||||
// Find the backpack icon position if available
|
||||
Transform backpackTransform = null;
|
||||
if (_cardAlbumUI != null && _cardAlbumUI.BackpackIcon != null)
|
||||
{
|
||||
// Get the world position of the backpack icon
|
||||
targetPosition = _cardAlbumUI.transform.Find("BackpackIcon").position;
|
||||
backpackTransform = _cardAlbumUI.BackpackIcon.transform;
|
||||
}
|
||||
else
|
||||
|
||||
if (backpackTransform == null)
|
||||
{
|
||||
// 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.");
|
||||
// If no backpack is found, just return to the menu
|
||||
UIPageController.Instance.PopPage();
|
||||
yield break;
|
||||
}
|
||||
|
||||
// Move each card to backpack with animation
|
||||
foreach (var cardUI in _revealedCards)
|
||||
|
||||
// Move each card to the backpack with slight delay between cards
|
||||
for (int i = 0; i < _revealedCards.Count; i++)
|
||||
{
|
||||
if (cardUI != null)
|
||||
CardUIElement card = _revealedCards[i];
|
||||
if (card != 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);
|
||||
// Get the world position of the backpack
|
||||
Vector3 backpackWorldPos = backpackTransform.position;
|
||||
|
||||
// Convert to local space of the card's parent for Tween
|
||||
Vector3 targetPos = card.transform.parent.InverseTransformPoint(backpackWorldPos);
|
||||
|
||||
// Start the move animation
|
||||
Tween.LocalPosition(card.transform, targetPos, 0.5f, cardMoveToBackpackDelay * i);
|
||||
Tween.LocalScale(card.transform, Vector3.zero, 0.5f, cardMoveToBackpackDelay * i);
|
||||
}
|
||||
|
||||
// Wait before starting the next card
|
||||
yield return new WaitForSeconds(cardMoveToBackpackDelay);
|
||||
}
|
||||
|
||||
// Wait for final animation
|
||||
|
||||
// Wait a bit after the last card
|
||||
yield return new WaitForSeconds(0.5f);
|
||||
|
||||
// Update state to completed
|
||||
|
||||
// Update state
|
||||
_currentState = OpeningState.Completed;
|
||||
|
||||
// Return to previous page
|
||||
|
||||
// Return to the menu
|
||||
UIPageController.Instance.PopPage();
|
||||
}
|
||||
|
||||
// Override for transition animations
|
||||
|
||||
/// <summary>
|
||||
/// Override for transition in animation using Pixelplacement.Tween
|
||||
/// </summary>
|
||||
protected override void DoTransitionIn(System.Action onComplete)
|
||||
{
|
||||
// Simple fade in animation
|
||||
@@ -415,10 +555,14 @@ namespace AppleHills.UI.CardSystem
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fallback if no CanvasGroup
|
||||
onComplete?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Override for transition out animation using Pixelplacement.Tween
|
||||
/// </summary>
|
||||
protected override void DoTransitionOut(System.Action onComplete)
|
||||
{
|
||||
// Simple fade out animation
|
||||
@@ -428,8 +572,29 @@ namespace AppleHills.UI.CardSystem
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fallback if no CanvasGroup
|
||||
onComplete?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// OnEnable override to ensure proper initialization
|
||||
/// </summary>
|
||||
private void OnEnable()
|
||||
{
|
||||
if (_cardManager == null)
|
||||
{
|
||||
_cardManager = CardSystemManager.Instance;
|
||||
}
|
||||
|
||||
if (_cardAlbumUI == null)
|
||||
{
|
||||
_cardAlbumUI = FindObjectOfType<CardAlbumUI>();
|
||||
}
|
||||
|
||||
// Re-cache card backs in case they changed while disabled
|
||||
CacheCardBackButtons();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user