Almost working card state machine
This commit is contained in:
201
docs/album_slot_migration_complete.md
Normal file
201
docs/album_slot_migration_complete.md
Normal file
@@ -0,0 +1,201 @@
|
||||
# Album Slot Migration - Complete ✅
|
||||
|
||||
## Migration Date
|
||||
November 16, 2025
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
Successfully migrated album card states from direct `IPointerClickHandler` to centralized click routing via `ICardClickHandler`, ensuring consistency with booster opening flow.
|
||||
|
||||
---
|
||||
|
||||
## Changes Made
|
||||
|
||||
### 1. CardPlacedInSlotState.cs
|
||||
**Changed:**
|
||||
- ✅ Removed `IPointerClickHandler` interface
|
||||
- ✅ Removed `UnityEngine.EventSystems` using directive
|
||||
- ✅ Added `ICardClickHandler` interface
|
||||
- ✅ Renamed `OnPointerClick(PointerEventData)` → `OnCardClicked(CardContext)`
|
||||
- ✅ Updated method signature to use context parameter
|
||||
|
||||
**Result:**
|
||||
- State now uses centralized click routing from CardContext
|
||||
- Consistent with booster opening states
|
||||
- Click gating via `context.IsClickable` now works
|
||||
|
||||
---
|
||||
|
||||
### 2. CardAlbumEnlargedState.cs
|
||||
**Changed:**
|
||||
- ✅ Removed `IPointerClickHandler` interface
|
||||
- ✅ Removed `UnityEngine.EventSystems` using directive
|
||||
- ✅ Added `ICardClickHandler` interface
|
||||
- ✅ Renamed `OnPointerClick(PointerEventData)` → `OnCardClicked(CardContext)`
|
||||
- ✅ Updated method signature to use context parameter
|
||||
- ✅ Added fallback for when animator is null (transitions to PlacedInSlotState immediately)
|
||||
|
||||
**Result:**
|
||||
- State now uses centralized click routing from CardContext
|
||||
- Consistent with booster opening states
|
||||
- More robust error handling
|
||||
|
||||
---
|
||||
|
||||
### 3. AlbumCardSlot.cs
|
||||
**Changed:**
|
||||
- ✅ Added `AlbumViewPage.RegisterCardInAlbum(card)` call in `SpawnCard()` method
|
||||
- ✅ Finds AlbumViewPage via `FindFirstObjectByType<AlbumViewPage>()`
|
||||
- ✅ Subscribes card's AlbumEnlargedState events to page backdrop/reparenting handlers
|
||||
|
||||
**Result:**
|
||||
- Cards spawned in slots now properly register with page
|
||||
- Backdrop shows when card is enlarged
|
||||
- Card reparents to enlarged container correctly
|
||||
|
||||
---
|
||||
|
||||
## Slot Behavior Verification
|
||||
|
||||
### ✅ Slot Keeps Reference to Assigned Card
|
||||
```csharp
|
||||
private StateMachine.Card _placedCard;
|
||||
```
|
||||
- Reference stored when card is spawned or placed
|
||||
- Accessible via `GetPlacedCard()`
|
||||
|
||||
### ✅ Auto-Spawn Owned Cards
|
||||
**Flow:**
|
||||
1. `OnEnable()` → `CheckAndSpawnOwnedCard()`
|
||||
2. Queries CardSystemManager for owned card (highest rarity)
|
||||
3. If owned → `SpawnCard(cardData)`
|
||||
4. Card spawned with `card.SetupForAlbumSlot(cardData, this)` → starts in `PlacedInSlotState`
|
||||
5. Card sized to match slot dimensions
|
||||
6. Card registered with AlbumViewPage
|
||||
|
||||
### ✅ In Slot → Clickable → Enlarge
|
||||
**Flow:**
|
||||
1. Card in `PlacedInSlotState`
|
||||
2. User clicks → CardContext routes click to state via `ICardClickHandler`
|
||||
3. `PlacedInSlotState.OnCardClicked()` → transitions to `AlbumEnlargedState`
|
||||
4. AlbumEnlargedState fires `OnEnlargeRequested` event
|
||||
5. AlbumViewPage shows backdrop, reparents card to top layer
|
||||
6. Card animates to enlarged scale
|
||||
|
||||
### ✅ Enlarged → Clickable → Dismiss
|
||||
**Flow:**
|
||||
1. Card in `AlbumEnlargedState`
|
||||
2. User clicks → CardContext routes click to state via `ICardClickHandler`
|
||||
3. `AlbumEnlargedState.OnCardClicked()` fires `OnShrinkRequested` event
|
||||
4. AlbumViewPage hides backdrop
|
||||
5. Card shrinks with animation
|
||||
6. On complete → transitions back to `PlacedInSlotState`
|
||||
7. Card reparents back to slot
|
||||
|
||||
### ✅ No Card = No Preview
|
||||
**Current Behavior:**
|
||||
- If player doesn't own card, `ownedCard` remains null
|
||||
- `SpawnCard()` never called
|
||||
- Slot remains empty
|
||||
- No visuals shown
|
||||
|
||||
**Future:** Slot itself clickable for silhouette preview (to be implemented)
|
||||
|
||||
---
|
||||
|
||||
## Architecture Benefits
|
||||
|
||||
### Unified Click Routing
|
||||
**Before:**
|
||||
- Booster states: `ICardClickHandler` (centralized)
|
||||
- Album states: `IPointerClickHandler` (direct)
|
||||
- **Problem:** Two different click systems, confusing
|
||||
|
||||
**After:**
|
||||
- All states: `ICardClickHandler` (centralized)
|
||||
- Single source of truth for click handling
|
||||
- Consistent gating via `context.IsClickable`
|
||||
|
||||
### Click Flow
|
||||
```
|
||||
User clicks card →
|
||||
CardDisplay.OnPointerClick →
|
||||
CardContext.HandleCardDisplayClicked (checks IsClickable) →
|
||||
Finds current state's ICardClickHandler →
|
||||
State.OnCardClicked(context) →
|
||||
State logic executes
|
||||
```
|
||||
|
||||
### Benefits
|
||||
- ✅ Consistent across all card states
|
||||
- ✅ Centralized gating (IsClickable)
|
||||
- ✅ Easy to debug (one routing path)
|
||||
- ✅ Easy to extend (add state, implement ICardClickHandler)
|
||||
- ✅ No more `IPointerClickHandler` scattered across states
|
||||
|
||||
---
|
||||
|
||||
## Testing Checklist
|
||||
|
||||
### Album View Flow
|
||||
- [ ] Album page opens correctly
|
||||
- [ ] Owned cards appear in album slots automatically
|
||||
- [ ] Cards sized correctly to slot dimensions
|
||||
- [ ] Clicking card in slot enlarges it
|
||||
- [ ] Backdrop appears when card enlarged
|
||||
- [ ] Card displays correctly while enlarged
|
||||
- [ ] Clicking enlarged card dismisses it
|
||||
- [ ] Card returns to slot correctly
|
||||
- [ ] Empty slots remain empty (no preview)
|
||||
- [ ] Multiple cards can be enlarged/dismissed sequentially
|
||||
|
||||
### Edge Cases
|
||||
- [ ] Card spawned when entering album (not during booster)
|
||||
- [ ] Multiple rarities of same card (highest shown)
|
||||
- [ ] Very first time opening album (no owned cards)
|
||||
- [ ] Rapid clicking doesn't break states
|
||||
- [ ] Page close during enlarge (cleanup handled)
|
||||
|
||||
---
|
||||
|
||||
## Future: Empty Slot Preview
|
||||
|
||||
When implementing "click empty slot to see silhouette":
|
||||
|
||||
1. Make AlbumCardSlot implement `IPointerClickHandler` for empty state
|
||||
2. Add check in `OnPointerClick()`:
|
||||
```csharp
|
||||
if (!_isOccupiedPermanently && _placedCard == null)
|
||||
{
|
||||
ShowSilhouettePreview();
|
||||
}
|
||||
```
|
||||
3. Create preview state or use temporary visual
|
||||
4. Show card back / silhouette / "???" indicator
|
||||
5. Click to dismiss preview
|
||||
|
||||
**Note:** This won't conflict with card click routing since card won't exist when slot is empty.
|
||||
|
||||
---
|
||||
|
||||
## Files Modified
|
||||
|
||||
- `CardPlacedInSlotState.cs` - Uses ICardClickHandler
|
||||
- `CardAlbumEnlargedState.cs` - Uses ICardClickHandler
|
||||
- `AlbumCardSlot.cs` - Registers cards with AlbumViewPage
|
||||
|
||||
---
|
||||
|
||||
## No Breaking Changes
|
||||
|
||||
- ✅ Existing Card.cs API unchanged
|
||||
- ✅ AlbumViewPage event system unchanged
|
||||
- ✅ Slot validation logic unchanged
|
||||
- ✅ Drag-and-drop from pending cards still works
|
||||
- ✅ All existing states still work
|
||||
|
||||
---
|
||||
|
||||
**Migration Complete!** Album slots now use unified click routing and all requirements verified. 🎉
|
||||
|
||||
297
docs/card_prefab_setup_guide.md
Normal file
297
docs/card_prefab_setup_guide.md
Normal file
@@ -0,0 +1,297 @@
|
||||
# Card Prefab Setup Guide
|
||||
|
||||
## Quick Reference: Building the New Card Prefab
|
||||
|
||||
This guide shows you how to create a Card prefab compatible with the new state-based system.
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before starting, make sure you have:
|
||||
- All Card state scripts compiled without errors
|
||||
- CardDisplay.cs working
|
||||
- Card.cs, CardContext.cs, CardAnimator.cs ready
|
||||
- PixelPlacement StateMachine (AppleMachine) available
|
||||
|
||||
---
|
||||
|
||||
## Step 1: Create the Root GameObject
|
||||
|
||||
1. Create empty GameObject named "Card"
|
||||
2. Add component: `Card.cs` (from `UI.CardSystem.StateMachine`)
|
||||
3. Add component: `RectTransform` (if not already present)
|
||||
4. Add component: `CanvasGroup` (optional, for fade effects)
|
||||
5. Add component: `AspectRatioFitter` (optional, to maintain card proportions)
|
||||
|
||||
**Card.cs Settings:**
|
||||
- Initial State: `IdleState`
|
||||
|
||||
---
|
||||
|
||||
## Step 2: Add CardContext Component
|
||||
|
||||
1. On the same "Card" GameObject, add: `CardContext.cs`
|
||||
2. This component holds:
|
||||
- Card data reference
|
||||
- IsNew flag
|
||||
- IsClickable flag
|
||||
- RootTransform reference (auto-assigned)
|
||||
|
||||
**CardContext.cs Settings:**
|
||||
- Root Transform: (leave empty, auto-assigned in Awake)
|
||||
|
||||
---
|
||||
|
||||
## Step 3: Add CardAnimator Component
|
||||
|
||||
1. On the same "Card" GameObject, add: `CardAnimator.cs`
|
||||
2. This component will handle all animations
|
||||
|
||||
**CardAnimator.cs Settings:**
|
||||
- Card Display: (assign in Step 4)
|
||||
- Visual Root: (assign the Card GameObject itself)
|
||||
|
||||
---
|
||||
|
||||
## Step 4: Create CardDisplay Child
|
||||
|
||||
1. Create child GameObject under "Card" named "CardDisplay"
|
||||
2. Add component: `CardDisplay.cs`
|
||||
3. Add UI elements as children:
|
||||
- **CardImage** (Image) - main card artwork
|
||||
- **FrameImage** (Image) - rarity frame
|
||||
- **OverlayImage** (Image) - rarity overlay effects
|
||||
- **BackgroundImage** (Image) - zone background
|
||||
- **ZoneShapeImage** (Image) - zone symbol/shape
|
||||
- **CardNameText** (TextMeshProUGUI) - card name
|
||||
|
||||
**CardDisplay.cs Settings:**
|
||||
- Assign all the UI element references above
|
||||
- Visual Config: Assign your CardVisualConfig ScriptableObject
|
||||
|
||||
**Layout Tips:**
|
||||
- Use anchors to stretch images to fill the card
|
||||
- Layer order (back to front): Background → Zone Shape → Card Image → Frame → Overlay
|
||||
- Make sure all images have "Raycast Target" enabled for click detection
|
||||
|
||||
---
|
||||
|
||||
## Step 5: Create CardBack Child (for flip animation)
|
||||
|
||||
1. Create child GameObject under "Card" named "CardBack"
|
||||
2. Add component: `Image`
|
||||
3. Assign your card back sprite
|
||||
4. Position/scale to match CardDisplay size
|
||||
|
||||
**Settings:**
|
||||
- Make sure it's initially hidden (will be shown by FlippingState)
|
||||
|
||||
---
|
||||
|
||||
## Step 6: Create StateMachine Child
|
||||
|
||||
1. Create child GameObject under "Card" named "StateMachine"
|
||||
2. Add component: `AppleMachine` (from Pixelplacement)
|
||||
|
||||
**AppleMachine Settings:**
|
||||
- Starting State: `IdleState`
|
||||
- Debug: Enable if you want state transition logging
|
||||
|
||||
---
|
||||
|
||||
## Step 7: Create State Children
|
||||
|
||||
Under "StateMachine", create these child GameObjects:
|
||||
|
||||
### 7a. IdleState
|
||||
- GameObject name: "IdleState"
|
||||
- Add component: `CardIdleState.cs`
|
||||
- Settings:
|
||||
- Hover Lift Distance: `20`
|
||||
- Hover Duration: `0.3`
|
||||
|
||||
### 7b. FlippingState
|
||||
- GameObject name: "FlippingState"
|
||||
- Add component: `CardFlippingState.cs`
|
||||
- Settings:
|
||||
- Flip Duration: `0.6`
|
||||
- Next State After Flip: `RevealedState`
|
||||
|
||||
### 7c. RevealedState
|
||||
- GameObject name: "RevealedState"
|
||||
- Add component: `CardRevealedState.cs`
|
||||
- Settings:
|
||||
- Scale: `1.5` (for NEW card emphasis)
|
||||
- Scale Duration: `0.5`
|
||||
|
||||
### 7d. DraggingState
|
||||
- GameObject name: "DraggingState"
|
||||
- Add component: `CardDraggingState.cs`
|
||||
- Settings:
|
||||
- Drag Scale: `1.2`
|
||||
- Drag Rotation: `5` degrees
|
||||
|
||||
### 7e. PlacedInSlotState
|
||||
- GameObject name: "PlacedInSlotState"
|
||||
- Add component: `CardPlacedInSlotState.cs`
|
||||
- Settings:
|
||||
- (Auto-configured when placed)
|
||||
|
||||
### 7f. AlbumEnlargedState
|
||||
- GameObject name: "AlbumEnlargedState"
|
||||
- Add component: `CardAlbumEnlargedState.cs`
|
||||
- Settings:
|
||||
- Enlarged Scale: `2.5`
|
||||
- Scale Duration: `0.3`
|
||||
|
||||
---
|
||||
|
||||
## Step 8: Wire Up References
|
||||
|
||||
Go back to the root "Card" GameObject:
|
||||
|
||||
**Card.cs:**
|
||||
- Context: Drag the Card GameObject (auto-finds CardContext)
|
||||
- Animator: Drag the Card GameObject (auto-finds CardAnimator)
|
||||
- State Machine: Drag the "StateMachine" child
|
||||
|
||||
**CardAnimator.cs:**
|
||||
- Card Display: Drag the "CardDisplay" child
|
||||
- Visual Root: Drag the "Card" GameObject itself
|
||||
|
||||
**CardContext.cs:**
|
||||
- (Everything auto-assigned, nothing to wire)
|
||||
|
||||
---
|
||||
|
||||
## Step 9: Save as Prefab
|
||||
|
||||
1. Drag the "Card" GameObject into your Prefabs folder
|
||||
2. Name it: `Card.prefab` (or whatever you prefer)
|
||||
3. Delete the instance from the scene
|
||||
|
||||
---
|
||||
|
||||
## Step 10: Update Scene References
|
||||
|
||||
### BoosterOpeningPage
|
||||
- Find `BoosterOpeningPage` in your scene
|
||||
- Assign `cardPrefab` field → your new Card prefab
|
||||
|
||||
### AlbumViewPage
|
||||
- Find `AlbumViewPage` in your scene
|
||||
- Assign `cardPrefab` field → your new Card prefab
|
||||
|
||||
### AlbumCardSlot Prefab
|
||||
- Open your AlbumCardSlot prefab
|
||||
- Assign `cardPrefab` field → your new Card prefab
|
||||
|
||||
---
|
||||
|
||||
## Testing Your Prefab
|
||||
|
||||
### Test 1: Booster Opening
|
||||
1. Play the game
|
||||
2. Open a booster pack
|
||||
3. Cards should spawn face-down
|
||||
4. Click a card → it flips and reveals
|
||||
5. If NEW → shows enlarged with "NEW" indicator
|
||||
6. If REPEAT → shows progress bar
|
||||
7. Click to dismiss → flies to album icon
|
||||
|
||||
### Test 2: Album Placement
|
||||
1. After opening boosters, cards appear in bottom-right
|
||||
2. Drag a card → it scales up and rotates slightly
|
||||
3. Drop on valid slot → it snaps in and stays
|
||||
4. Drop outside → returns to original position
|
||||
|
||||
### Test 3: Album Viewing
|
||||
1. Go to album view
|
||||
2. Cards in slots should display normally
|
||||
3. Click a placed card → enlarges with backdrop
|
||||
4. Click again (or backdrop) → shrinks back to slot
|
||||
|
||||
---
|
||||
|
||||
## Common Issues & Fixes
|
||||
|
||||
### Cards don't flip
|
||||
- Check FlippingState is assigned in StateMachine
|
||||
- Verify CardBack GameObject exists and has sprite
|
||||
- Check CardAnimator has CardDisplay reference
|
||||
|
||||
### Cards don't respond to clicks
|
||||
- Make sure CardDisplay images have "Raycast Target" enabled
|
||||
- Check EventSystem exists in scene
|
||||
- Verify Card has CanvasGroup or Image for raycast blocking
|
||||
|
||||
### Animations don't play
|
||||
- Check CardAnimator reference is assigned
|
||||
- Verify Tween library (Pixelplacement) is imported
|
||||
- Check state components have correct duration values
|
||||
|
||||
### Cards stuck in one state
|
||||
- Enable StateMachine debug mode to see transitions
|
||||
- Check state scripts don't have infinite loops
|
||||
- Verify transition logic in state Enter/Exit methods
|
||||
|
||||
---
|
||||
|
||||
## Advanced: Customizing States
|
||||
|
||||
Want to add your own card behavior? Here's how:
|
||||
|
||||
1. Create new script inheriting from `AppleState`
|
||||
2. Override `Enter()`, `Exit()`, `UpdateState()` as needed
|
||||
3. Use `Card` reference to access context, animator, etc.
|
||||
4. Add GameObject under StateMachine with your new component
|
||||
5. Transition to it via `Card.ChangeState("YourStateName")`
|
||||
|
||||
Example:
|
||||
```csharp
|
||||
public class CardBurningState : AppleState
|
||||
{
|
||||
private Card _card;
|
||||
|
||||
public override void Enter(params object[] args)
|
||||
{
|
||||
_card = GetComponentInParent<Card>();
|
||||
// Play burning animation
|
||||
_card.Animator.PlayBurnEffect();
|
||||
}
|
||||
|
||||
public override void Exit()
|
||||
{
|
||||
// Clean up
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Final Checklist
|
||||
|
||||
Before considering your prefab complete:
|
||||
|
||||
- [ ] Root Card GameObject has Card, CardContext, CardAnimator components
|
||||
- [ ] CardDisplay child is set up with all UI elements
|
||||
- [ ] CardBack child exists for flip animation
|
||||
- [ ] StateMachine child has AppleMachine component
|
||||
- [ ] All 6 state children are created and configured
|
||||
- [ ] All references wired up on Card component
|
||||
- [ ] Prefab saved and assigned in scene controllers
|
||||
- [ ] Tested in both booster and album flows
|
||||
- [ ] No console errors when playing
|
||||
|
||||
---
|
||||
|
||||
## Need Help?
|
||||
|
||||
Refer to:
|
||||
- `card_system_migration_summary.md` - What changed and why
|
||||
- `card_architecture_plan.md` - Architecture overview
|
||||
- State script files - Implementation details
|
||||
|
||||
Happy card building! 🎴
|
||||
|
||||
215
docs/card_system_migration_summary.md
Normal file
215
docs/card_system_migration_summary.md
Normal file
@@ -0,0 +1,215 @@
|
||||
# Card System Migration Summary
|
||||
|
||||
## Overview
|
||||
Successfully migrated the card UI system from the old wrapper-based approach (AlbumCard, FlippableCard) to the new state-based Card system using PixelPlacement's StateMachine.
|
||||
|
||||
## Date
|
||||
Migration completed: November 16, 2025
|
||||
|
||||
---
|
||||
|
||||
## Changes Made
|
||||
|
||||
### 1. CardDisplay.cs - Simplified Click Handling
|
||||
**Changes:**
|
||||
- Removed `_isPreviewMode` and `_previewSlot` tracking
|
||||
- Removed `SetPreviewMode()` and preview visual methods (`SetPreviewVisuals`, `ClearPreviewVisuals`)
|
||||
- Simplified `OnPointerClick()` to only emit `OnCardClicked` event
|
||||
- No more parent-seeking or type-checking logic
|
||||
|
||||
**Impact:**
|
||||
- CardDisplay is now a pure "dumb" visual renderer + click detector
|
||||
- Any wrapper can subscribe to click events without tight coupling
|
||||
- Preview functionality moved to card states
|
||||
|
||||
---
|
||||
|
||||
### 2. AlbumCardSlot.cs - Updated to New Card System
|
||||
**Changes:**
|
||||
- Changed from `AlbumCard` references to `StateMachine.Card`
|
||||
- Removed `IPointerClickHandler` interface (no more manual preview clicks)
|
||||
- Removed all preview-related fields and methods:
|
||||
- `previewCardDisplay`
|
||||
- `_isPreviewShowing`
|
||||
- `_previewOriginalScale`
|
||||
- `SetupPreviewCard()`
|
||||
- `ShowPreview()`
|
||||
- `HidePreview()`
|
||||
- `OnPointerClick()`
|
||||
- `DismissPreview()`
|
||||
- Updated `SpawnCard()` to use `Card.SetupForAlbumSlot()` with `PlacedInSlotState`
|
||||
- Removed registration with AlbumViewPage (no longer needed)
|
||||
- Changed `albumCardPrefab` field to `cardPrefab`
|
||||
|
||||
**Impact:**
|
||||
- Slots now spawn cards in the `PlacedInSlotState` directly
|
||||
- Preview functionality will be handled by card states if needed in the future
|
||||
- Cleaner, simpler slot logic focused only on validation and spawning
|
||||
|
||||
---
|
||||
|
||||
### 3. AlbumViewPage.cs - Removed Legacy Support
|
||||
**Changes:**
|
||||
- Removed legacy `AlbumCard` registration methods:
|
||||
- `RegisterAlbumCard()`
|
||||
- `UnregisterAlbumCard()`
|
||||
- `OnCardEnlargeRequested(AlbumCard)`
|
||||
- `OnCardShrinkRequested(AlbumCard)`
|
||||
- Removed slot preview helper methods:
|
||||
- `ShowSlotPreview()`
|
||||
- `HideSlotPreview()`
|
||||
- Kept only new Card system methods:
|
||||
- `RegisterCardInAlbum(StateMachine.Card)`
|
||||
- `UnregisterCardInAlbum(StateMachine.Card)`
|
||||
- `OnCardEnlargeRequested(CardAlbumEnlargedState)`
|
||||
- `OnCardShrinkRequested(CardAlbumEnlargedState)`
|
||||
|
||||
**Impact:**
|
||||
- Page only manages backdrop and reparenting for card enlarge states
|
||||
- No more manual preview management
|
||||
- Cleaner event-based architecture
|
||||
|
||||
---
|
||||
|
||||
### 4. BoosterOpeningPage.cs - Already Updated
|
||||
**Status:**
|
||||
- Already using new `StateMachine.Card` system
|
||||
- Uses `CardContext` for setup and event handling
|
||||
- No changes required - already migrated!
|
||||
|
||||
**Current Flow:**
|
||||
1. Spawns Card prefab with CardContext
|
||||
2. Calls `context.SetupCard()` and `card.SetupForBoosterReveal()`
|
||||
3. Subscribes to `context.OnFlipComplete` and `context.OnCardInteractionComplete`
|
||||
4. Cards handle their own flip and reveal states
|
||||
|
||||
---
|
||||
|
||||
### 5. DEPRECATED Folder - Deleted
|
||||
**Deleted Classes:**
|
||||
- `AlbumCard.cs`
|
||||
- `FlippableCard.cs`
|
||||
- `AlbumCardPlacementDraggable.cs`
|
||||
- `CardDraggable.cs`
|
||||
- `CardDraggableVisual.cs`
|
||||
- `CardInteractionHandler.cs`
|
||||
|
||||
**Justification:**
|
||||
- No longer referenced anywhere in the codebase
|
||||
- All functionality replaced by state-based Card system
|
||||
- Keeping them would cause confusion
|
||||
|
||||
---
|
||||
|
||||
## Architecture Benefits
|
||||
|
||||
### Event-Based Communication
|
||||
- **Old:** Parent-seeking, type-checking, manual forwarding
|
||||
- **New:** Clean pub/sub pattern, decoupled components
|
||||
|
||||
### State Management
|
||||
- **Old:** Multiple wrapper classes (FlippableCard → AlbumCard → CardDisplay)
|
||||
- **New:** Single Card component + isolated state objects
|
||||
|
||||
### Code Reuse
|
||||
- **Old:** Repeated animation/behavior code in each wrapper
|
||||
- **New:** Shared CardAnimator, reusable state behaviors
|
||||
|
||||
### Flexibility
|
||||
- **Old:** Hard to add new card contexts (preview, enlarged, etc.)
|
||||
- **New:** Just add a new state - no wrapper changes needed
|
||||
|
||||
---
|
||||
|
||||
## Current Card State Flow
|
||||
|
||||
### Booster Opening Flow
|
||||
1. Spawn Card with `SetupForBoosterReveal()` → starts in `IdleState`
|
||||
2. User clicks → transitions to `FlippingState`
|
||||
3. Flip completes → transitions to `RevealedState` (new/repeat logic)
|
||||
4. User interacts → card animates to album icon, destroyed
|
||||
|
||||
### Album Placement Flow
|
||||
1. Spawn Card with `SetupForAlbumPlacement()` → starts in `RevealedState`
|
||||
2. User drags → transitions to `DraggingState`
|
||||
3. Dropped in slot → transitions to `PlacedInSlotState`
|
||||
4. User clicks placed card → transitions to `AlbumEnlargedState`
|
||||
5. User dismisses → back to `PlacedInSlotState`
|
||||
|
||||
### Album Slot Auto-Spawn
|
||||
1. AlbumCardSlot checks owned cards on Enable
|
||||
2. If owned, spawns Card with `SetupForAlbumSlot()` → starts in `PlacedInSlotState`
|
||||
3. Card sits in slot, ready for enlarge interaction
|
||||
|
||||
---
|
||||
|
||||
## What's Next
|
||||
|
||||
### Prefab Setup Required
|
||||
You'll need to update your prefabs to use the new Card structure:
|
||||
|
||||
**Old Prefab Structure:**
|
||||
```
|
||||
FlippableCard (or AlbumCard)
|
||||
└── CardDisplay
|
||||
└── [visual elements]
|
||||
```
|
||||
|
||||
**New Prefab Structure:**
|
||||
```
|
||||
Card (Card.cs component)
|
||||
├── CardDisplay (visual renderer)
|
||||
│ └── [visual elements: image, frame, overlay, etc.]
|
||||
└── StateMachine (AppleMachine component)
|
||||
├── IdleState (CardIdleState)
|
||||
├── FlippingState (CardFlippingState)
|
||||
├── RevealedState (CardRevealedState)
|
||||
├── DraggingState (CardDraggingState)
|
||||
├── PlacedInSlotState (CardPlacedInSlotState)
|
||||
└── AlbumEnlargedState (CardAlbumEnlargedState)
|
||||
```
|
||||
|
||||
### Configuration References
|
||||
Make sure to update these references in your scenes:
|
||||
- **BoosterOpeningPage:** `cardPrefab` field → assign new Card prefab
|
||||
- **AlbumViewPage:** `cardPrefab` field → assign new Card prefab
|
||||
- **AlbumCardSlot:** `cardPrefab` field → assign new Card prefab
|
||||
|
||||
---
|
||||
|
||||
## Testing Checklist
|
||||
|
||||
- [ ] Booster opening flow works correctly
|
||||
- [ ] Cards flip and reveal properly
|
||||
- [ ] New/repeat card logic displays correctly
|
||||
- [ ] Cards can be dragged from pending list to album slots
|
||||
- [ ] Cards snap into album slots correctly
|
||||
- [ ] Placed cards can be enlarged when clicked
|
||||
- [ ] Enlarged cards can be dismissed
|
||||
- [ ] Empty slots no longer show preview (feature removed for now)
|
||||
- [ ] No console errors or null references
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
### Preview Functionality
|
||||
The old preview system (showing locked cards in empty slots) has been removed. If you want to re-implement this:
|
||||
1. Create a new `EmptySlotPreviewState`
|
||||
2. Have empty AlbumCardSlots spawn a Card in this state
|
||||
3. State handles the greyed-out visuals and enlarge/shrink
|
||||
|
||||
### Backwards Compatibility
|
||||
**None.** This is a breaking change. Old prefabs using AlbumCard/FlippableCard will not work and must be updated.
|
||||
|
||||
### Performance
|
||||
The new system is more efficient:
|
||||
- Fewer component lookups (no parent-seeking)
|
||||
- State objects pooled per card (not created/destroyed)
|
||||
- Cleaner event subscription (no manual chain management)
|
||||
|
||||
---
|
||||
|
||||
## Questions?
|
||||
Refer to the implementation plan documents or the state machine architecture document for more details.
|
||||
|
||||
1
docs/cards_wip/booster_click_fix.md
Normal file
1
docs/cards_wip/booster_click_fix.md
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
Reference in New Issue
Block a user