From 95daea8d34febba198cd42f9f99f4d429ea77191 Mon Sep 17 00:00:00 2001 From: Michal Pikulski Date: Thu, 6 Nov 2025 11:11:15 +0100 Subject: [PATCH] Code up the card part --- Assets/Scripts/UI/CardSystem/AlbumViewPage.cs | 4 + .../UI/CardSystem/BoosterOpeningPage.cs | 398 ++++++++++++++- Assets/Scripts/UI/CardSystem/DragDrop.meta | 3 + .../DragDrop/BoosterPackDraggable.cs | 120 +++++ .../DragDrop/BoosterPackDraggable.cs.meta | 3 + .../CardSystem/DragDrop/BoosterPackVisual.cs | 189 +++++++ .../DragDrop/BoosterPackVisual.cs.meta | 3 + .../UI/CardSystem/DragDrop/CardDraggable.cs | 62 +++ .../CardSystem/DragDrop/CardDraggable.cs.meta | 3 + .../DragDrop/CardDraggableVisual.cs | 121 +++++ .../DragDrop/CardDraggableVisual.cs.meta | 3 + Assets/Scripts/UI/DragAndDrop.meta | 3 + Assets/Scripts/UI/DragAndDrop/Core.meta | 3 + .../UI/DragAndDrop/Core/DraggableObject.cs | 476 ++++++++++++++++++ .../DragAndDrop/Core/DraggableObject.cs.meta | 3 + .../UI/DragAndDrop/Core/DraggableSlot.cs | 139 +++++ .../UI/DragAndDrop/Core/DraggableSlot.cs.meta | 3 + .../UI/DragAndDrop/Core/DraggableVisual.cs | 367 ++++++++++++++ .../DragAndDrop/Core/DraggableVisual.cs.meta | 3 + .../UI/DragAndDrop/Core/SlotContainer.cs | 258 ++++++++++ .../UI/DragAndDrop/Core/SlotContainer.cs.meta | 3 + docs/booster_opening_setup_guide.md | 365 ++++++++++++++ docs/booster_prefab_structure_guide.md | 342 +++++++++++++ docs/drag_drop_system_readme.md | 309 ++++++++++++ 24 files changed, 3179 insertions(+), 4 deletions(-) create mode 100644 Assets/Scripts/UI/CardSystem/DragDrop.meta create mode 100644 Assets/Scripts/UI/CardSystem/DragDrop/BoosterPackDraggable.cs create mode 100644 Assets/Scripts/UI/CardSystem/DragDrop/BoosterPackDraggable.cs.meta create mode 100644 Assets/Scripts/UI/CardSystem/DragDrop/BoosterPackVisual.cs create mode 100644 Assets/Scripts/UI/CardSystem/DragDrop/BoosterPackVisual.cs.meta create mode 100644 Assets/Scripts/UI/CardSystem/DragDrop/CardDraggable.cs create mode 100644 Assets/Scripts/UI/CardSystem/DragDrop/CardDraggable.cs.meta create mode 100644 Assets/Scripts/UI/CardSystem/DragDrop/CardDraggableVisual.cs create mode 100644 Assets/Scripts/UI/CardSystem/DragDrop/CardDraggableVisual.cs.meta create mode 100644 Assets/Scripts/UI/DragAndDrop.meta create mode 100644 Assets/Scripts/UI/DragAndDrop/Core.meta create mode 100644 Assets/Scripts/UI/DragAndDrop/Core/DraggableObject.cs create mode 100644 Assets/Scripts/UI/DragAndDrop/Core/DraggableObject.cs.meta create mode 100644 Assets/Scripts/UI/DragAndDrop/Core/DraggableSlot.cs create mode 100644 Assets/Scripts/UI/DragAndDrop/Core/DraggableSlot.cs.meta create mode 100644 Assets/Scripts/UI/DragAndDrop/Core/DraggableVisual.cs create mode 100644 Assets/Scripts/UI/DragAndDrop/Core/DraggableVisual.cs.meta create mode 100644 Assets/Scripts/UI/DragAndDrop/Core/SlotContainer.cs create mode 100644 Assets/Scripts/UI/DragAndDrop/Core/SlotContainer.cs.meta create mode 100644 docs/booster_opening_setup_guide.md create mode 100644 docs/booster_prefab_structure_guide.md create mode 100644 docs/drag_drop_system_readme.md diff --git a/Assets/Scripts/UI/CardSystem/AlbumViewPage.cs b/Assets/Scripts/UI/CardSystem/AlbumViewPage.cs index 71b2190e..6f7d88c6 100644 --- a/Assets/Scripts/UI/CardSystem/AlbumViewPage.cs +++ b/Assets/Scripts/UI/CardSystem/AlbumViewPage.cs @@ -153,6 +153,10 @@ namespace UI.CardSystem { if (boosterOpeningPage != null && UIPageController.Instance != null) { + // Pass current booster count to the opening page + int boosterCount = CardSystemManager.Instance?.GetBoosterPackCount() ?? 0; + boosterOpeningPage.SetAvailableBoosterCount(boosterCount); + UIPageController.Instance.PushPage(boosterOpeningPage); } } diff --git a/Assets/Scripts/UI/CardSystem/BoosterOpeningPage.cs b/Assets/Scripts/UI/CardSystem/BoosterOpeningPage.cs index ba14c0e6..4146f81a 100644 --- a/Assets/Scripts/UI/CardSystem/BoosterOpeningPage.cs +++ b/Assets/Scripts/UI/CardSystem/BoosterOpeningPage.cs @@ -1,9 +1,12 @@ -using System.Collections; +using System.Collections; using System.Collections.Generic; +using System.Linq; using AppleHills.Data.CardSystem; using Data.CardSystem; using Pixelplacement; using UI.Core; +using UI.CardSystem.DragDrop; +using UI.DragAndDrop.Core; using UnityEngine; using UnityEngine.UI; @@ -11,7 +14,7 @@ namespace UI.CardSystem { /// /// UI page for opening booster packs and displaying the cards received. - /// Automatically triggers the opening when the page is shown. + /// Manages the entire booster opening flow with drag-and-drop interaction. /// public class BoosterOpeningPage : UIPage { @@ -19,13 +22,26 @@ namespace UI.CardSystem [SerializeField] private CanvasGroup canvasGroup; [SerializeField] private Button closeButton; + [Header("Booster Management")] + [SerializeField] private GameObject[] boosterPackInstances; // Booster prefabs/instances + [SerializeField] private SlotContainer bottomRightSlots; // Holds waiting boosters + [SerializeField] private DraggableSlot centerOpeningSlot; // Where booster goes to open + [Header("Card Display")] [SerializeField] private Transform cardDisplayContainer; - [SerializeField] private CardDisplay cardDisplayPrefab; + [SerializeField] private GameObject flippableCardPrefab; // Placeholder for card backs + [SerializeField] private float cardSpacing = 150f; [Header("Settings")] [SerializeField] private float cardRevealDelay = 0.5f; - [SerializeField] private float cardSpacing = 50f; + [SerializeField] private float boosterDisappearDuration = 0.5f; + + private int _availableBoosterCount; + private BoosterPackDraggable _currentBoosterInCenter; + private List _currentRevealedCards = new List(); + private CardData[] _currentCardData; + private int _revealedCardCount; + private bool _isProcessingOpening; private void Awake() { @@ -51,6 +67,15 @@ namespace UI.CardSystem { closeButton.onClick.RemoveListener(OnCloseButtonClicked); } + + // Unsubscribe from slot events + if (centerOpeningSlot != null) + { + centerOpeningSlot.OnOccupied -= OnBoosterPlacedInCenter; + } + + // Unsubscribe from booster events + UnsubscribeFromAllBoosters(); } private void OnCloseButtonClicked() @@ -61,6 +86,371 @@ namespace UI.CardSystem } } + /// + /// Set the number of available booster packs before showing the page + /// + public void SetAvailableBoosterCount(int count) + { + _availableBoosterCount = count; + } + + public override void TransitionIn() + { + base.TransitionIn(); + InitializeBoosterDisplay(); + } + + public override void TransitionOut() + { + CleanupPage(); + base.TransitionOut(); + } + + /// + /// Initialize the booster pack display based on available count + /// + private void InitializeBoosterDisplay() + { + if (boosterPackInstances == null || boosterPackInstances.Length == 0) + { + Debug.LogWarning("BoosterOpeningPage: No booster pack instances assigned!"); + return; + } + + // Calculate how many boosters to show (capped by array size) + int visibleCount = Mathf.Min(_availableBoosterCount, boosterPackInstances.Length); + + // Show/hide boosters and assign to slots + for (int i = 0; i < boosterPackInstances.Length; i++) + { + if (boosterPackInstances[i] == null) continue; + + bool shouldShow = i < visibleCount; + boosterPackInstances[i].SetActive(shouldShow); + + if (shouldShow) + { + // Get the booster draggable component + BoosterPackDraggable booster = boosterPackInstances[i].GetComponent(); + if (booster != null) + { + // Reset state + booster.ResetTapCount(); + booster.SetTapToOpenEnabled(false); // Disable tap-to-open until in center + + // Subscribe to events + booster.OnReadyToOpen += OnBoosterReadyToOpen; + + // Assign to bottom-right slot if slots available + if (bottomRightSlots != null && i < bottomRightSlots.SlotCount) + { + DraggableSlot slot = bottomRightSlots.GetSlotAtIndex(i); + if (slot != null) + { + booster.AssignToSlot(slot, false); + } + } + } + } + } + + // Subscribe to center slot events + if (centerOpeningSlot != null) + { + centerOpeningSlot.OnOccupied += OnBoosterPlacedInCenter; + } + } + + /// + /// Handle when a booster is placed in the center opening slot + /// + private void OnBoosterPlacedInCenter(DraggableObject draggable) + { + BoosterPackDraggable booster = draggable as BoosterPackDraggable; + if (booster == null) return; + + _currentBoosterInCenter = booster; + + // Lock the slot so it can't be dragged out + centerOpeningSlot.SetLocked(true); + + // Enable tap-to-open and reset tap count + booster.ResetTapCount(); + booster.SetTapToOpenEnabled(true); + } + + /// + /// Handle tap-to-place: When player taps a booster in bottom slots, move it to center + /// + public void OnBoosterTappedInBottomSlot(BoosterPackDraggable booster) + { + if (_currentBoosterInCenter != null || centerOpeningSlot == null) + return; // Center slot already occupied + + // Move booster to center slot + booster.AssignToSlot(centerOpeningSlot, true); + } + + /// + /// Handle when booster is ready to open (after max taps) + /// + private void OnBoosterReadyToOpen(BoosterPackDraggable booster) + { + if (_isProcessingOpening) return; + + StartCoroutine(ProcessBoosterOpening(booster)); + } + + /// + /// Process the booster opening sequence + /// + private IEnumerator ProcessBoosterOpening(BoosterPackDraggable booster) + { + _isProcessingOpening = true; + + // Call CardSystemManager to open the pack + if (CardSystemManager.Instance != null) + { + List revealedCardsList = CardSystemManager.Instance.OpenBoosterPack(); + _currentCardData = revealedCardsList.ToArray(); + + // Animate booster disappearing + yield return StartCoroutine(AnimateBoosterDisappear(booster)); + + // Show card backs + SpawnCardBacks(_currentCardData.Length); + + // Wait for player to reveal all cards + yield return StartCoroutine(WaitForCardReveals()); + + // Check if more boosters available + _availableBoosterCount--; + + if (_availableBoosterCount > 0) + { + // Show next booster + yield return StartCoroutine(ShowNextBooster()); + } + else + { + // No more boosters, auto-close page + yield return new WaitForSeconds(1f); + if (UIPageController.Instance != null) + { + UIPageController.Instance.PopPage(); + } + } + } + + _isProcessingOpening = false; + } + + /// + /// Animate the booster pack disappearing + /// + private IEnumerator AnimateBoosterDisappear(BoosterPackDraggable booster) + { + if (booster == null) yield break; + + // Scale down and fade out + Transform boosterTransform = booster.transform; + + Tween.LocalScale(boosterTransform, Vector3.zero, boosterDisappearDuration, 0f, Tween.EaseInBack); + + // Also fade the visual if it has a CanvasGroup + CanvasGroup boosterCg = booster.GetComponentInChildren(); + if (boosterCg != null) + { + Tween.Value(1f, 0f, (val) => boosterCg.alpha = val, boosterDisappearDuration, 0f); + } + + yield return new WaitForSeconds(boosterDisappearDuration); + + // Destroy the booster + Destroy(booster.gameObject); + _currentBoosterInCenter = null; + + // Unlock center slot + centerOpeningSlot.SetLocked(false); + } + + /// + /// Spawn card back placeholders for revealing + /// + private void SpawnCardBacks(int count) + { + if (flippableCardPrefab == null || cardDisplayContainer == null) + { + Debug.LogWarning("BoosterOpeningPage: Missing card prefab or container!"); + return; + } + + _currentRevealedCards.Clear(); + _revealedCardCount = 0; + + // Calculate positions + float totalWidth = (count - 1) * cardSpacing; + float startX = -totalWidth / 2f; + + for (int i = 0; i < count; i++) + { + GameObject cardObj = Instantiate(flippableCardPrefab, cardDisplayContainer); + RectTransform cardRect = cardObj.GetComponent(); + + if (cardRect != null) + { + cardRect.anchoredPosition = new Vector2(startX + (i * cardSpacing), 0); + } + + // Add button to handle reveal on click + Button cardButton = cardObj.GetComponent