13 KiB
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
- In Unity Project window, right-click in
Assets/Data/CardSystem/ - Select Create → AppleHills → Card Animation Config
- Name it
CardAnimationConfig - Configure settings (these match your current FlippableCard settings):
- Flip Animation
- Flip Duration:
0.6 - Flip Scale Punch:
1.1
- Flip Duration:
- Enlarge Animation
- Enlarged Scale:
2.5 - Scale Duration:
0.3
- Enlarged Scale:
- Hover Animation
- Hover Height:
10 - Hover Duration:
1.5 - Hover Scale Multiplier:
1.05
- Hover Height:
- Drag Animation
- Drag Scale:
1.1 - Snap Duration:
0.4
- Drag Scale:
- Flip Animation
Step 2: Create Base Card Prefab
Create Root GameObject
- In Hierarchy, right-click → Create Empty
- Name it
Card - Add Component → Rect Transform (converts to UI element)
- Set Anchors to center-middle
- Set Size to
200 x 280(standard card size)
Add Core Components to Root
-
Add CardContext component:
- Click Add Component → search
CardContext - Leave references empty for now (will auto-find)
- Click Add Component → search
-
Add CardAnimator component:
- Click Add Component → search
CardAnimator - Drag
CardAnimationConfigasset to Config field
- Click Add Component → search
-
Add Card component:
- Click Add Component → search
Card - Set Initial State to
IdleState
- Click Add Component → search
Step 3: Add CardDisplay (From Existing Prefab)
Option A: If you have existing CardDisplay prefab
- Drag
CardDisplayprefab into hierarchy as child ofCard - Position at
(0, 0, 0)local position - Ensure it fills the card area
Option B: Create CardDisplay from scratch
- Right-click
Cardin hierarchy → Create Empty - Name it
CardDisplay - Add Component → Card Display (your existing script)
- 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
- Assign these to CardDisplay component fields
Step 4: Create State Machine Hierarchy
Create StateMachine GameObject
- Right-click
Card→ Create Empty - Name it
CardStateMachine - Add Component → Apple Machine (from Pixelplacement)
- 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
- Right-click
CardStateMachine→ Create Empty - Name it
IdleState - Add Component → Card Idle State
- No child visuals needed for this state
2. FlippingState
- Right-click
CardStateMachine→ Create Empty - Name it
FlippingState - Add Component → Card Flipping State
- 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
- Right-click
3. RevealedState
- Right-click
CardStateMachine→ Create Empty - Name it
RevealedState - Add Component → Card Revealed State
- No child visuals needed for this state
4. EnlargedNewState
- Right-click
CardStateMachine→ Create Empty - Name it
EnlargedNewState - Add Component → Card Enlarged New State
- 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
NewCardBadgeto New Card Badge field on CardEnlargedNewState
- Right-click
5. EnlargedRepeatState
- Right-click
CardStateMachine→ Create Empty - Name it
EnlargedRepeatState - Add Component → Card Enlarged Repeat State
- 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
ProgressBarContainerto Progress Bar Container field - Drag fill bar to Progress Bar Fill field
- Drag text to Progress Text field
- Set Cards To Upgrade to
5
- Right-click
6. DraggingState
- Right-click
CardStateMachine→ Create Empty - Name it
DraggingState - Add Component → Card Dragging State
- Set Drag Scale to
1.1 - No child visuals needed for this state
7. PlacedInSlotState
- Right-click
CardStateMachine→ Create Empty - Name it
PlacedInSlotState - Add Component → Card Placed In Slot State
- No child visuals needed for this state
8. AlbumEnlargedState
- Right-click
CardStateMachine→ Create Empty - Name it
AlbumEnlargedState - Add Component → Card Album Enlarged State
- No child visuals needed for this state
Step 5: Wire Up References
On CardStateMachine (AppleMachine component)
- Select
CardStateMachineGameObject - Set Default State to
IdleStateGameObject (drag from hierarchy)
On Card Root (Card component)
- Select root
CardGameObject - Context should auto-find CardContext component
- Animator should auto-find CardAnimator component
- State Machine should auto-find CardStateMachine/AppleMachine
- If not auto-found, drag components manually
On CardContext Component
- Select root
CardGameObject - In CardContext component:
- Card Display: Drag
CardDisplaychild GameObject - Card Animator: Should auto-find on same GameObject
- State Machine: Should auto-find CardStateMachine child
- Card Display: Drag
Step 6: Test the State Machine
Test in Editor (Play Mode)
- Select root
Cardin hierarchy - In Card component, call
SetupCard()from inspector (you'll need test data) - Watch the state machine transition through states
- Check CardStateMachine → Current State field to see active state
- 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
- Drag the root
CardGameObject from hierarchy toAssets/Prefabs/UI/CardSystem/ - Name it
Card.prefab - Delete the instance from hierarchy (prefab is saved)
Step 8: Integration with Existing Code
Spawning New Cards (BoosterOpeningPage example)
Old code:
GameObject cardObj = Instantiate(flippableCardPrefab, cardDisplayContainer);
FlippableCard card = cardObj.GetComponent<FlippableCard>();
card.SetupCard(cardData);
New code:
GameObject cardObj = Instantiate(cardPrefab, cardDisplayContainer);
Card card = cardObj.GetComponent<Card>();
card.SetupForBoosterReveal(cardData, isNew: true);
Placing Cards in Album (AlbumViewPage example)
Old code:
AlbumCard albumCard = Instantiate(albumCardPrefab, slot.transform);
albumCard.SetupCard(cardData);
albumCard.SetParentSlot(slot);
New code:
Card card = Instantiate(cardPrefab, slot.transform);
card.SetupForAlbumSlot(cardData, slot);
Listening to State Events
Example - Listening for card reveal:
Card card = GetComponent<Card>();
var flippingState = card.GetStateComponent<CardFlippingState>("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
- Right-click
Card.prefab→ Create → Prefab Variant - Name it
BoosterCard.prefab - Adjust initial state to
IdleState - Customize appearance if needed
AlbumCard Variant
- Right-click
Card.prefab→ Create → Prefab Variant - Name it
AlbumCard.prefab - Adjust initial state to
PlacedInSlotState - 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
-
Test Booster Opening Flow:
- Open BoosterOpeningPage scene
- Replace FlippableCard prefab references with Card prefab
- Test pack opening, card reveal, new/repeat states
-
Test Album Flow:
- Open AlbumViewPage scene
- Replace AlbumCard prefab references with Card prefab
- Test placing cards in slots, enlarging from album
-
Performance Testing:
- Spawn 10+ cards at once
- Check frame rate, tween performance
- Verify no memory leaks from state transitions
-
Clean Up Old Code:
- Once new system is stable, deprecate:
FlippableCard.csAlbumCard.csAlbumCardPlacementDraggable.cs(if fully replaced)
- Keep
CardDisplay.cs(still used!) - Archive old prefabs for reference
- Once new system is stable, deprecate:
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! 🎉