Files
AppleHillsProduction/docs/cards_wip/card_prefab_assembly_guide.md
Michal Pikulski 4fdbbb0aa8 Add roadmap docs
2025-11-15 20:37:01 +01:00

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

  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 CardCreate 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 CardStateMachineCreate Empty
  2. Name it IdleState
  3. Add Component → Card Idle State
  4. No child visuals needed for this state

2. FlippingState

  1. Right-click CardStateMachineCreate Empty
  2. Name it FlippingState
  3. Add Component → Card Flipping State
  4. Create CardBackVisual child:
    • Right-click FlippingStateUI → 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 CardStateMachineCreate Empty
  2. Name it RevealedState
  3. Add Component → Card Revealed State
  4. No child visuals needed for this state

4. EnlargedNewState

  1. Right-click CardStateMachineCreate Empty
  2. Name it EnlargedNewState
  3. Add Component → Card Enlarged New State
  4. Create NewCardBadge child:
    • Right-click EnlargedNewStateCreate 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 CardStateMachineCreate Empty
  2. Name it EnlargedRepeatState
  3. Add Component → Card Enlarged Repeat State
  4. Create ProgressBarUI child:
    • Right-click EnlargedRepeatStateCreate 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 CardStateMachineCreate 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 CardStateMachineCreate 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 CardStateMachineCreate 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:

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

  1. Right-click Card.prefabCreate → Prefab Variant
  2. Name it BoosterCard.prefab
  3. Adjust initial state to IdleState
  4. Customize appearance if needed

AlbumCard Variant

  1. Right-click Card.prefabCreate → 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! 🎉