# Card Prefab Assembly Guide ## Overview This guide walks you through creating the new Card prefab with state machine architecture while integrating with existing CardDisplay components. --- ## Step 1: Create CardAnimationConfig Asset 1. In Unity Project window, right-click in `Assets/Data/CardSystem/` 2. Select **Create → AppleHills → Card Animation Config** 3. Name it `CardAnimationConfig` 4. Configure settings (these match your current FlippableCard settings): - **Flip Animation** - Flip Duration: `0.6` - Flip Scale Punch: `1.1` - **Enlarge Animation** - Enlarged Scale: `2.5` - Scale Duration: `0.3` - **Hover Animation** - Hover Height: `10` - Hover Duration: `1.5` - Hover Scale Multiplier: `1.05` - **Drag Animation** - Drag Scale: `1.1` - Snap Duration: `0.4` --- ## Step 2: Create Base Card Prefab ### Create Root GameObject 1. In Hierarchy, right-click → **Create Empty** 2. Name it `Card` 3. Add Component → **Rect Transform** (converts to UI element) 4. Set **Anchors** to center-middle 5. Set **Size** to `200 x 280` (standard card size) ### Add Core Components to Root 1. **Add CardContext component:** - Click **Add Component** → search `CardContext` - Leave references empty for now (will auto-find) 2. **Add CardAnimator component:** - Click **Add Component** → search `CardAnimator` - Drag `CardAnimationConfig` asset to **Config** field 3. **Add Card component:** - Click **Add Component** → search `Card` - Set **Initial State** to `IdleState` --- ## Step 3: Add CardDisplay (From Existing Prefab) ### Option A: If you have existing CardDisplay prefab 1. Drag `CardDisplay` prefab into hierarchy as child of `Card` 2. Position at `(0, 0, 0)` local position 3. Ensure it fills the card area ### Option B: Create CardDisplay from scratch 1. Right-click `Card` in hierarchy → **Create Empty** 2. Name it `CardDisplay` 3. Add Component → **Card Display** (your existing script) 4. Setup UI elements as children: - Add **Image** for card image - Add **TextMeshProUGUI** for card name - Add **Image** for frame - Add **Image** for overlay - Add **Image** for background - Add **Image** for zone shape 5. Assign these to CardDisplay component fields --- ## Step 4: Create State Machine Hierarchy ### Create StateMachine GameObject 1. Right-click `Card` → **Create Empty** 2. Name it `CardStateMachine` 3. Add Component → **Apple Machine** (from Pixelplacement) 4. Configure AppleMachine: - **Verbose**: unchecked (unless debugging) - **Allow Reentry**: unchecked - **Return To Default On Disable**: checked ### Create State GameObjects (as children of CardStateMachine) For each state, follow this pattern: #### 1. IdleState 1. Right-click `CardStateMachine` → **Create Empty** 2. Name it `IdleState` 3. Add Component → **Card Idle State** 4. **No child visuals needed** for this state #### 2. FlippingState 1. Right-click `CardStateMachine` → **Create Empty** 2. Name it `FlippingState` 3. Add Component → **Card Flipping State** 4. **Create CardBackVisual child:** - Right-click `FlippingState` → **UI → Image** - Name it `CardBackVisual` - Set **Anchors** to stretch-stretch - Set **Left/Right/Top/Bottom** to `0` - Assign your card back sprite to **Source Image** - Drag this to **Card Back Visual** field on CardFlippingState component #### 3. RevealedState 1. Right-click `CardStateMachine` → **Create Empty** 2. Name it `RevealedState` 3. Add Component → **Card Revealed State** 4. **No child visuals needed** for this state #### 4. EnlargedNewState 1. Right-click `CardStateMachine` → **Create Empty** 2. Name it `EnlargedNewState` 3. Add Component → **Card Enlarged New State** 4. **Create NewCardBadge child:** - Right-click `EnlargedNewState` → **Create Empty** - Name it `NewCardBadge` - Add child **UI → Image** for badge background - Add child **UI → TextMeshProUGUI** for "NEW CARD" text - Position badge at top of card (e.g., Y offset +100) - Drag parent `NewCardBadge` to **New Card Badge** field on CardEnlargedNewState #### 5. EnlargedRepeatState 1. Right-click `CardStateMachine` → **Create Empty** 2. Name it `EnlargedRepeatState` 3. Add Component → **Card Enlarged Repeat State** 4. **Create ProgressBarUI child:** - Right-click `EnlargedRepeatState` → **Create Empty** - Name it `ProgressBarContainer` - Add child **UI → Image** for background bar - Add child **UI → Image** for fill bar (set Image Type to **Filled**) - Add child **UI → TextMeshProUGUI** for "X/5" text - Position at bottom of card (e.g., Y offset -100) - Drag `ProgressBarContainer` to **Progress Bar Container** field - Drag fill bar to **Progress Bar Fill** field - Drag text to **Progress Text** field - Set **Cards To Upgrade** to `5` #### 6. DraggingState 1. Right-click `CardStateMachine` → **Create Empty** 2. Name it `DraggingState` 3. Add Component → **Card Dragging State** 4. Set **Drag Scale** to `1.1` 5. **No child visuals needed** for this state #### 7. PlacedInSlotState 1. Right-click `CardStateMachine` → **Create Empty** 2. Name it `PlacedInSlotState` 3. Add Component → **Card Placed In Slot State** 4. **No child visuals needed** for this state #### 8. AlbumEnlargedState 1. Right-click `CardStateMachine` → **Create Empty** 2. Name it `AlbumEnlargedState` 3. Add Component → **Card Album Enlarged State** 4. **No child visuals needed** for this state --- ## Step 5: Wire Up References ### On CardStateMachine (AppleMachine component) 1. Select `CardStateMachine` GameObject 2. Set **Default State** to `IdleState` GameObject (drag from hierarchy) ### On Card Root (Card component) 1. Select root `Card` GameObject 2. **Context** should auto-find CardContext component 3. **Animator** should auto-find CardAnimator component 4. **State Machine** should auto-find CardStateMachine/AppleMachine 5. If not auto-found, drag components manually ### On CardContext Component 1. Select root `Card` GameObject 2. In CardContext component: - **Card Display**: Drag `CardDisplay` child GameObject - **Card Animator**: Should auto-find on same GameObject - **State Machine**: Should auto-find CardStateMachine child --- ## Step 6: Test the State Machine ### Test in Editor (Play Mode) 1. Select root `Card` in hierarchy 2. In Card component, call `SetupCard()` from inspector (you'll need test data) 3. Watch the state machine transition through states 4. Check **CardStateMachine → Current State** field to see active state 5. Click the card to trigger state transitions ### Debug Tips - Enable **Verbose** on AppleMachine to see state change logs - Watch hierarchy - active state GameObject will be enabled (blue icon) - Inactive states will be disabled (gray icon) - State-owned visuals (CardBackVisual, NewCardBadge, etc.) should activate/deactivate with their parent state --- ## Step 7: Save as Prefab 1. Drag the root `Card` GameObject from hierarchy to `Assets/Prefabs/UI/CardSystem/` 2. Name it `Card.prefab` 3. Delete the instance from hierarchy (prefab is saved) --- ## Step 8: Integration with Existing Code ### Spawning New Cards (BoosterOpeningPage example) **Old code:** ```csharp GameObject cardObj = Instantiate(flippableCardPrefab, cardDisplayContainer); FlippableCard card = cardObj.GetComponent(); card.SetupCard(cardData); ``` **New code:** ```csharp GameObject cardObj = Instantiate(cardPrefab, cardDisplayContainer); Card card = cardObj.GetComponent(); card.SetupForBoosterReveal(cardData, isNew: true); ``` ### Placing Cards in Album (AlbumViewPage example) **Old code:** ```csharp AlbumCard albumCard = Instantiate(albumCardPrefab, slot.transform); albumCard.SetupCard(cardData); albumCard.SetParentSlot(slot); ``` **New code:** ```csharp Card card = Instantiate(cardPrefab, slot.transform); card.SetupForAlbumSlot(cardData, slot); ``` ### Listening to State Events **Example - Listening for card reveal:** ```csharp Card card = GetComponent(); var flippingState = card.GetStateComponent("FlippingState"); // Subscribe to flip complete (you may need to add custom events) // Or check current state: if (card.GetCurrentStateName() == "RevealedState") { // Card was revealed } ``` --- ## Step 9: Create Prefab Variants (Optional) You can create variants for different card contexts: ### BoosterCard Variant 1. Right-click `Card.prefab` → **Create → Prefab Variant** 2. Name it `BoosterCard.prefab` 3. Adjust initial state to `IdleState` 4. Customize appearance if needed ### AlbumCard Variant 1. Right-click `Card.prefab` → **Create → Prefab Variant** 2. Name it `AlbumCard.prefab` 3. Adjust initial state to `PlacedInSlotState` 4. Remove states not needed (like IdleState, FlippingState if cards are pre-placed) --- ## Hierarchy Reference (Final Structure) ``` Card (RectTransform) ├─ [CardContext component] ├─ [CardAnimator component] ├─ [Card component] ├─ CardDisplay │ ├─ CardImage (Image) │ ├─ CardNameText (TextMeshProUGUI) │ ├─ FrameImage (Image) │ ├─ OverlayImage (Image) │ ├─ BackgroundImage (Image) │ └─ ZoneShapeImage (Image) └─ CardStateMachine ├─ [AppleMachine component] ├─ IdleState │ └─ [CardIdleState component] ├─ FlippingState │ ├─ [CardFlippingState component] │ └─ CardBackVisual (Image) ├─ RevealedState │ └─ [CardRevealedState component] ├─ EnlargedNewState │ ├─ [CardEnlargedNewState component] │ └─ NewCardBadge │ ├─ BadgeBackground (Image) │ └─ BadgeText (TextMeshProUGUI) ├─ EnlargedRepeatState │ ├─ [CardEnlargedRepeatState component] │ └─ ProgressBarContainer │ ├─ BarBackground (Image) │ ├─ BarFill (Image - Filled type) │ └─ CountText (TextMeshProUGUI) ├─ DraggingState │ └─ [CardDraggingState component] ├─ PlacedInSlotState │ └─ [CardPlacedInSlotState component] └─ AlbumEnlargedState └─ [CardAlbumEnlargedState component] ``` --- ## Troubleshooting ### Issue: States not transitioning - **Check:** AppleMachine **Default State** is assigned - **Check:** State names match exactly (case-sensitive: "IdleState" not "idlestate") - **Check:** Enable **Verbose** on AppleMachine to see logs ### Issue: Visuals not showing - **Check:** State-owned visuals (CardBackVisual, etc.) are assigned in state components - **Check:** Images have sprites assigned - **Check:** RectTransforms are sized properly (not 0x0) ### Issue: CardContext references null - **Check:** CardDisplay is assigned on CardContext component - **Check:** CardAnimator has CardAnimationConfig asset assigned - **Check:** All components are on correct GameObjects ### Issue: Animations not playing - **Check:** CardAnimationConfig asset is assigned to CardAnimator - **Check:** Tween system (Pixelplacement) is in project - **Check:** Config values are not zero ### Issue: Click not working - **Check:** Canvas has **Graphic Raycaster** component - **Check:** EventSystem exists in scene - **Check:** Card has **CanvasGroup** with **Blocks Raycasts** enabled (or Image component) - **Check:** State components implement IPointerClickHandler (IdleState, RevealedState, etc.) --- ## Migration Checklist - [ ] Created CardAnimationConfig asset - [ ] Created base Card prefab with all components - [ ] Created all 8 state GameObjects under CardStateMachine - [ ] Assigned state-owned visuals (CardBackVisual, NewCardBadge, ProgressBarUI) - [ ] Wired up all component references - [ ] Tested state transitions in Play mode - [ ] Saved as prefab - [ ] Updated BoosterOpeningPage to use new Card prefab - [ ] Updated AlbumViewPage to use new Card prefab - [ ] Tested booster opening flow - [ ] Tested album placement flow - [ ] Tested enlarge/shrink interactions - [ ] (Optional) Deprecated old prefabs (FlippableCard, AlbumCard, etc.) --- ## Next Steps After Prefab Creation 1. **Test Booster Opening Flow:** - Open BoosterOpeningPage scene - Replace FlippableCard prefab references with Card prefab - Test pack opening, card reveal, new/repeat states 2. **Test Album Flow:** - Open AlbumViewPage scene - Replace AlbumCard prefab references with Card prefab - Test placing cards in slots, enlarging from album 3. **Performance Testing:** - Spawn 10+ cards at once - Check frame rate, tween performance - Verify no memory leaks from state transitions 4. **Clean Up Old Code:** - Once new system is stable, deprecate: - `FlippableCard.cs` - `AlbumCard.cs` - `AlbumCardPlacementDraggable.cs` (if fully replaced) - Keep `CardDisplay.cs` (still used!) - Archive old prefabs for reference --- ## Success Criteria ✅ Card prefab created with 8 functional states ✅ State transitions work (Idle → Flipping → Revealed, etc.) ✅ State-owned visuals activate/deactivate automatically ✅ Animations play correctly (flip, enlarge, hover) ✅ Click interactions work in all states ✅ Integration with BoosterOpeningPage works ✅ Integration with AlbumViewPage works ✅ No console errors during state transitions ✅ Performance is acceptable (60fps with multiple cards) Once all criteria met, you have successfully migrated to the new card system! 🎉