Working visual part
This commit is contained in:
147
docs/QUICK_SETUP_CHECKLIST.md
Normal file
147
docs/QUICK_SETUP_CHECKLIST.md
Normal file
@@ -0,0 +1,147 @@
|
||||
# 🎯 Quick Setup Checklist - Copy This!
|
||||
|
||||
## ✅ What's Done (By AI)
|
||||
|
||||
- ✅ Created `BoosterVisual.prefab` in `Assets/Prefabs/UI/DragAndDrop/`
|
||||
- ✅ Created `BoosterPackPrefab.prefab` in `Assets/Prefabs/UI/Cards/`
|
||||
- ✅ Created `FlippableCardPrefab.prefab` in `Assets/Prefabs/UI/Cards/`
|
||||
- ✅ BoosterVisual has TiltParent, ShakeParent, PackImage structure
|
||||
- ✅ All components are added
|
||||
|
||||
---
|
||||
|
||||
## 📝 What YOU Need To Do (Quick Version)
|
||||
|
||||
### **1. BoosterVisual.prefab** (2 minutes)
|
||||
```
|
||||
Open prefab → Select root
|
||||
├─ Assign: TiltParent → to "Tilt Parent" field
|
||||
├─ Assign: ShakeParent → to "Shake Parent" field
|
||||
├─ Assign: TiltParent/PackImage → to "Pack Image" field
|
||||
└─ Assign: YOUR SPRITE → to "Pack Sprite" field
|
||||
|
||||
Select TiltParent/PackImage
|
||||
└─ Uncheck "Raycast Target" on Image component
|
||||
```
|
||||
|
||||
### **2. BoosterPackPrefab.prefab** (1 minute)
|
||||
```
|
||||
Open prefab → Select root
|
||||
├─ Set size: 200x300
|
||||
├─ Check "Raycast Target" on Image component
|
||||
├─ Assign: BoosterVisual.prefab → to "Visual Prefab" field
|
||||
├─ Check: "Can Tap To Open"
|
||||
└─ Set: "Max Taps To Open" = 3
|
||||
```
|
||||
|
||||
### **3. FlippableCardPrefab.prefab** (1 minute)
|
||||
```
|
||||
Open prefab → Select root
|
||||
├─ Set size: 200x300
|
||||
└─ Assign: YOUR CARD BACK SPRITE → to Image sprite
|
||||
```
|
||||
|
||||
### **4. BoosterOpeningPage.prefab** (10 minutes)
|
||||
```
|
||||
Open prefab → Add children manually:
|
||||
|
||||
CREATE THESE CHILDREN:
|
||||
├─ CloseButton (UI > Button)
|
||||
├─ BottomRightContainer (Empty + SlotContainer component)
|
||||
│ ├─ Slot_0 (Empty + DraggableSlot)
|
||||
│ ├─ Slot_1 (Empty + DraggableSlot)
|
||||
│ └─ Slot_2 (Empty + DraggableSlot)
|
||||
├─ CenterSlot (Empty + DraggableSlot)
|
||||
│ └─ IMPORTANT: Apply Scale = ✓, Scale = (2,2,1)
|
||||
├─ CardDisplayContainer (Empty)
|
||||
└─ BoosterInstances (Empty)
|
||||
├─ Drag BoosterPackPrefab → name "BoosterPack_0" → Uncheck Active
|
||||
├─ Drag BoosterPackPrefab → name "BoosterPack_1" → Uncheck Active
|
||||
└─ Drag BoosterPackPrefab → name "BoosterPack_2" → Uncheck Active
|
||||
|
||||
WIRE UP ROOT COMPONENT:
|
||||
Select BoosterOpeningPage root → Assign all references:
|
||||
├─ Close Button → CloseButton
|
||||
├─ Booster Pack Instances [0-2] → BoosterPack_0, 1, 2
|
||||
├─ Bottom Right Slots → BottomRightContainer
|
||||
├─ Center Opening Slot → CenterSlot
|
||||
├─ Card Display Container → CardDisplayContainer
|
||||
└─ Flippable Card Prefab → FlippableCardPrefab.prefab
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Critical Settings
|
||||
|
||||
### **CenterSlot (Most Important!)**
|
||||
```yaml
|
||||
Apply Scale To Occupant: ✓ CHECK THIS!
|
||||
Occupant Scale: (2, 2, 1) # Makes booster 2x bigger
|
||||
Filter By Type: ✓
|
||||
Allowed Type Names: ["BoosterPackDraggable"]
|
||||
```
|
||||
|
||||
### **BottomRightContainer SlotContainer**
|
||||
```yaml
|
||||
Layout Type: Vertical
|
||||
Spacing: 120
|
||||
Center Slots: ✓
|
||||
Auto Register Children: ✓
|
||||
```
|
||||
|
||||
### **Each Bottom Slot (Slot_0, 1, 2)**
|
||||
```yaml
|
||||
Filter By Type: ✓
|
||||
Allowed Type Names: ["BoosterPackDraggable"]
|
||||
Apply Scale To Occupant: ☐ UNCHECKED (normal size)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⚡ Super Quick Start
|
||||
|
||||
**Fastest path to testing:**
|
||||
|
||||
1. Open `BoosterVisual.prefab` → Assign 4 references → Save
|
||||
2. Open `BoosterPackPrefab.prefab` → Assign BoosterVisual, check tap settings → Save
|
||||
3. Open `FlippableCardPrefab.prefab` → Assign sprite → Save
|
||||
4. Open `BoosterOpeningPage.prefab` → Build child structure (see above) → Wire references → Save
|
||||
5. Test!
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Sprite Assignments Needed
|
||||
|
||||
You need to assign these sprites:
|
||||
|
||||
1. **Booster Pack Sprite** → BoosterVisual/PackImage
|
||||
2. **Card Back Sprite** → FlippableCardPrefab
|
||||
3. **Optional: Background** → BoosterOpeningPage/Background
|
||||
|
||||
---
|
||||
|
||||
## 🐛 If Something Doesn't Work
|
||||
|
||||
**Can't drag booster:**
|
||||
→ Check BoosterPackPrefab base Image has raycastTarget = ✓
|
||||
|
||||
**Booster doesn't scale in center:**
|
||||
→ Check CenterSlot "Apply Scale To Occupant" = ✓
|
||||
|
||||
**Taps don't work:**
|
||||
→ Check "Can Tap To Open" = ✓ on booster
|
||||
|
||||
**No boosters show:**
|
||||
→ Check they're assigned in BoosterOpeningPage component
|
||||
→ Check CardSystemManager has boosters available
|
||||
|
||||
---
|
||||
|
||||
## 📄 Full Details
|
||||
|
||||
See `SETUP_COMPLETE_Manual_Steps.md` for detailed step-by-step instructions!
|
||||
|
||||
---
|
||||
|
||||
**Estimated Time:** 15-20 minutes total 🕐
|
||||
|
||||
343
docs/SETUP_COMPLETE_Manual_Steps.md
Normal file
343
docs/SETUP_COMPLETE_Manual_Steps.md
Normal file
@@ -0,0 +1,343 @@
|
||||
# ✅ Booster Opening System - Auto-Generated Prefabs & Manual Setup
|
||||
|
||||
## 🎉 What I Created For You
|
||||
|
||||
I've successfully created the following prefabs using Unity MCP:
|
||||
|
||||
### ✅ **Created Prefabs:**
|
||||
|
||||
1. **`Assets/Prefabs/UI/DragAndDrop/BoosterVisual.prefab`**
|
||||
- Base visual prefab for booster packs
|
||||
- Has: Canvas, CanvasGroup, BoosterPackVisual component
|
||||
- Has children: TiltParent (with PackImage), ShakeParent
|
||||
|
||||
2. **`Assets/Prefabs/UI/Cards/BoosterPackPrefab.prefab`**
|
||||
- Main draggable booster prefab
|
||||
- Has: Image, BoosterPackDraggable component
|
||||
- Ready for visual prefab assignment
|
||||
|
||||
3. **`Assets/Prefabs/UI/Cards/FlippableCardPrefab.prefab`**
|
||||
- Card reveal prefab
|
||||
- Has: Image, CardDisplay, Button components
|
||||
- Ready for sprite assignment
|
||||
|
||||
### 📋 **Existing Prefab:**
|
||||
4. **`Assets/Prefabs/UI/Cards/BoosterOpeningPage.prefab`**
|
||||
- Already has: RectTransform, CanvasGroup, BoosterOpeningPage component
|
||||
- Needs child structure added (see below)
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Manual Setup Required
|
||||
|
||||
Due to Unity MCP limitations with editing existing prefabs, you'll need to complete the setup manually. Here's EXACTLY what to do:
|
||||
|
||||
### **STEP 1: Configure BoosterVisual Prefab**
|
||||
|
||||
1. Open `Assets/Prefabs/UI/DragAndDrop/BoosterVisual.prefab`
|
||||
2. Select the root `BoosterVisual` object
|
||||
3. In **BoosterPackVisual** component, assign references:
|
||||
- Tilt Parent: Drag `TiltParent` child
|
||||
- Shake Parent: Drag `ShakeParent` child
|
||||
- Pack Image: Drag `TiltParent/PackImage`
|
||||
- Pack Sprite: **[YOU ASSIGN]** - Your booster pack sprite asset
|
||||
4. Set these values:
|
||||
```
|
||||
Follow Speed: 30
|
||||
Rotation Amount: 20
|
||||
Rotation Speed: 20
|
||||
Auto Tilt Amount: 30
|
||||
Manual Tilt Amount: 20
|
||||
Tilt Speed: 20
|
||||
Use Scale Animations: ✓
|
||||
Scale On Hover: 1.15
|
||||
Scale On Drag: 1.25
|
||||
Use Idle Animation: ✓
|
||||
Idle Animation Speed: 1
|
||||
Opening Scale Punch: 0.5
|
||||
Opening Rotation Punch: 360
|
||||
Opening Duration: 0.5
|
||||
```
|
||||
5. Select `TiltParent/PackImage`
|
||||
6. Set **Image** component:
|
||||
- Raycast Target: ☐ **UNCHECK THIS**
|
||||
- Size: 180x280 (or adjust to fit)
|
||||
7. Save prefab
|
||||
|
||||
---
|
||||
|
||||
### **STEP 2: Configure BoosterPackPrefab**
|
||||
|
||||
1. Open `Assets/Prefabs/UI/Cards/BoosterPackPrefab.prefab`
|
||||
2. Select root `BoosterPackPrefab`
|
||||
3. Set **RectTransform**:
|
||||
- Width: 200
|
||||
- Height: 300
|
||||
4. Set **Image** component:
|
||||
- Sprite: **[YOU ASSIGN]** - Placeholder or your booster sprite
|
||||
- Raycast Target: ✓ **MUST BE CHECKED**
|
||||
5. Set **BoosterPackDraggable** component:
|
||||
```
|
||||
Move Speed: 50
|
||||
Smooth Movement: ✓
|
||||
Snap Duration: 0.3
|
||||
Visual Prefab: [Drag BoosterVisual.prefab]
|
||||
Instantiate Visual: ✓
|
||||
Is Selectable: ✓
|
||||
Selection Offset: 50
|
||||
Can Open On Drop: ☐
|
||||
Can Open On Double Click: ☐
|
||||
Can Tap To Open: ✓
|
||||
Max Taps To Open: 3
|
||||
```
|
||||
6. Save prefab
|
||||
|
||||
---
|
||||
|
||||
### **STEP 3: Configure FlippableCardPrefab**
|
||||
|
||||
1. Open `Assets/Prefabs/UI/Cards/FlippableCardPrefab.prefab`
|
||||
2. Select root `FlippableCardPrefab`
|
||||
3. Set **RectTransform**:
|
||||
- Width: 200
|
||||
- Height: 300
|
||||
4. Set **Image** component:
|
||||
- Sprite: **[YOU ASSIGN]** - Card back sprite
|
||||
- Raycast Target: ✓
|
||||
5. **CardDisplay** component will be configured at runtime
|
||||
6. **Button** component is ready (OnClick added at runtime)
|
||||
7. Save prefab
|
||||
|
||||
---
|
||||
|
||||
### **STEP 4: Build BoosterOpeningPage Structure**
|
||||
|
||||
⚠️ **IMPORTANT:** You need to manually add children to the BoosterOpeningPage prefab.
|
||||
|
||||
1. Open `Assets/Prefabs/UI/Cards/BoosterOpeningPage.prefab` in Prefab mode
|
||||
2. Add the following structure:
|
||||
|
||||
```
|
||||
BoosterOpeningPage (root - already exists)
|
||||
├── Background (optional)
|
||||
│ └── [Create: UI > Image]
|
||||
│ └── [Set: Full screen, dark semi-transparent]
|
||||
│
|
||||
├── CloseButton
|
||||
│ └── [Create: UI > Button - TextMeshPro]
|
||||
│ └── [Position: Top-right corner]
|
||||
│ └── [Text: "X" or "Close"]
|
||||
│
|
||||
├── BottomRightContainer
|
||||
│ └── [Create: Empty GameObject]
|
||||
│ └── [Add Component: SlotContainer]
|
||||
│ └── [Position: X=800, Y=-400 (adjust for your canvas)]
|
||||
│ └── [Anchor: Bottom-Right]
|
||||
│ └── [Children: 3 slots below]
|
||||
│ │
|
||||
│ ├── Slot_0
|
||||
│ │ └── [Create: Empty GameObject]
|
||||
│ │ └── [Add Component: DraggableSlot]
|
||||
│ │ └── [Size: 150x200]
|
||||
│ │
|
||||
│ ├── Slot_1
|
||||
│ │ └── [Same as Slot_0]
|
||||
│ │
|
||||
│ └── Slot_2
|
||||
│ └── [Same as Slot_0]
|
||||
│
|
||||
├── CenterSlot
|
||||
│ └── [Create: Empty GameObject]
|
||||
│ └── [Add Component: DraggableSlot]
|
||||
│ └── [Position: Center (0, 0)]
|
||||
│ └── [Size: 300x400]
|
||||
│ └── [Anchor: Middle Center]
|
||||
│
|
||||
├── CardDisplayContainer
|
||||
│ └── [Create: Empty GameObject]
|
||||
│ └── [Position: Center (0, -100)]
|
||||
│ └── [Anchor: Middle Center]
|
||||
│
|
||||
└── BoosterInstances
|
||||
└── [Create: Empty GameObject]
|
||||
└── [Children: 3 booster instances below]
|
||||
│
|
||||
├── BoosterPack_0
|
||||
│ └── [Drag in: BoosterPackPrefab]
|
||||
│ └── [Set Active: ☐ UNCHECKED]
|
||||
│
|
||||
├── BoosterPack_1
|
||||
│ └── [Drag in: BoosterPackPrefab]
|
||||
│ └── [Set Active: ☐ UNCHECKED]
|
||||
│
|
||||
└── BoosterPack_2
|
||||
└── [Drag in: BoosterPackPrefab]
|
||||
└── [Set Active: ☐ UNCHECKED]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### **STEP 5: Configure BottomRightContainer (SlotContainer)**
|
||||
|
||||
1. Select `BottomRightContainer`
|
||||
2. Set **RectTransform**:
|
||||
- Anchor: Bottom-Right
|
||||
- Pivot: (1, 0)
|
||||
- Position: X=-100, Y=100 (offset from corner)
|
||||
3. Set **SlotContainer** component:
|
||||
```
|
||||
Layout Type: Vertical
|
||||
Spacing: 120
|
||||
Center Slots: ✓
|
||||
Auto Register Children: ✓
|
||||
```
|
||||
4. For each child slot (Slot_0, Slot_1, Slot_2):
|
||||
- Width: 150, Height: 200
|
||||
- **DraggableSlot** settings:
|
||||
```
|
||||
Slot Index: 0, 1, 2 (respectively)
|
||||
Is Locked: ☐
|
||||
Filter By Type: ✓
|
||||
Allowed Type Names: ["BoosterPackDraggable"]
|
||||
Apply Scale To Occupant: ☐
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### **STEP 6: Configure CenterSlot (Opening Slot)**
|
||||
|
||||
1. Select `CenterSlot`
|
||||
2. Set **RectTransform**:
|
||||
- Anchor: Middle Center
|
||||
- Position: (0, 0)
|
||||
- Width: 300, Height: 400
|
||||
3. Set **DraggableSlot** component:
|
||||
```
|
||||
Slot Index: 0
|
||||
Is Locked: ☐
|
||||
Filter By Type: ✓
|
||||
Allowed Type Names: ["BoosterPackDraggable"]
|
||||
Apply Scale To Occupant: ✓ ← IMPORTANT!
|
||||
Occupant Scale: (2, 2, 1) ← IMPORTANT!
|
||||
Scale Transition Duration: 0.3
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### **STEP 7: Wire Up BoosterOpeningPage Component**
|
||||
|
||||
1. Select root `BoosterOpeningPage`
|
||||
2. In **BoosterOpeningPage** component, assign:
|
||||
```
|
||||
[UI References]
|
||||
Canvas Group: [Auto-assigned or drag it]
|
||||
Close Button: [Drag CloseButton]
|
||||
|
||||
[Booster Management]
|
||||
Booster Pack Instances (Array size: 3):
|
||||
Element 0: [Drag BoosterPack_0]
|
||||
Element 1: [Drag BoosterPack_1]
|
||||
Element 2: [Drag BoosterPack_2]
|
||||
Bottom Right Slots: [Drag BottomRightContainer]
|
||||
Center Opening Slot: [Drag CenterSlot]
|
||||
|
||||
[Card Display]
|
||||
Card Display Container: [Drag CardDisplayContainer]
|
||||
Flippable Card Prefab: [Drag FlippableCardPrefab.prefab]
|
||||
Card Spacing: 150
|
||||
|
||||
[Settings]
|
||||
Card Reveal Delay: 0.5
|
||||
Booster Disappear Duration: 0.5
|
||||
Transition Duration: 0.3
|
||||
```
|
||||
3. Save prefab
|
||||
|
||||
---
|
||||
|
||||
## ✅ Final Checklist
|
||||
|
||||
Before testing, verify:
|
||||
|
||||
### **BoosterVisual.prefab:**
|
||||
- [ ] TiltParent and ShakeParent are assigned in component
|
||||
- [ ] Pack Image is assigned in component
|
||||
- [ ] Pack Sprite is assigned (your asset)
|
||||
- [ ] PackImage has raycastTarget = false
|
||||
|
||||
### **BoosterPackPrefab.prefab:**
|
||||
- [ ] Size is 200x300
|
||||
- [ ] Base Image has raycastTarget = TRUE
|
||||
- [ ] Visual Prefab is assigned (BoosterVisual)
|
||||
- [ ] Can Tap To Open = ✓
|
||||
- [ ] Max Taps To Open = 3
|
||||
|
||||
### **FlippableCardPrefab.prefab:**
|
||||
- [ ] Size is 200x300
|
||||
- [ ] Has card back sprite assigned
|
||||
- [ ] Has CardDisplay component
|
||||
- [ ] Has Button component
|
||||
|
||||
### **BoosterOpeningPage.prefab:**
|
||||
- [ ] Has all children created (see structure above)
|
||||
- [ ] BottomRightContainer has 3 DraggableSlots
|
||||
- [ ] CenterSlot has scale settings configured
|
||||
- [ ] BoosterInstances has 3 inactive booster prefab instances
|
||||
- [ ] All references assigned in BoosterOpeningPage component
|
||||
|
||||
---
|
||||
|
||||
## 🎮 Testing
|
||||
|
||||
1. **Test in Scene:**
|
||||
- Add BoosterOpeningPage prefab to your scene
|
||||
- Make sure it's a child of your Canvas
|
||||
- Start inactive (UIPage system controls visibility)
|
||||
|
||||
2. **Test Boosters:**
|
||||
- Set CardSystemManager booster count to 3
|
||||
- Open album → Click booster button
|
||||
- Should see 3 boosters in bottom-right
|
||||
|
||||
3. **Test Drag:**
|
||||
- Drag a booster to center
|
||||
- Should scale up to 2x
|
||||
|
||||
4. **Test Taps:**
|
||||
- Tap booster 3 times
|
||||
- Should shake progressively
|
||||
- Should disappear and show cards
|
||||
|
||||
---
|
||||
|
||||
## 📝 What You Still Need To Do
|
||||
|
||||
1. **Assign Sprites:**
|
||||
- Booster pack sprite to BoosterVisual/PackImage
|
||||
- Card back sprite to FlippableCardPrefab
|
||||
|
||||
2. **Build Page Structure:**
|
||||
- Add all children to BoosterOpeningPage as outlined
|
||||
- Position elements appropriately for your canvas size
|
||||
|
||||
3. **Wire References:**
|
||||
- Assign all the references in BoosterOpeningPage component
|
||||
|
||||
4. **Visual Polish:**
|
||||
- Add optional particle effects to BoosterVisual
|
||||
- Style the close button
|
||||
- Add background image
|
||||
|
||||
---
|
||||
|
||||
## 💡 Tips
|
||||
|
||||
- **Canvas Size:** Adjust positions based on your canvas reference resolution
|
||||
- **Testing:** Test one piece at a time (boosters, then slots, then page)
|
||||
- **Sprites:** Use placeholder sprites initially, replace later
|
||||
- **Debugging:** Enable Gizmos to see slot positions
|
||||
|
||||
---
|
||||
|
||||
🎉 **Three prefabs are ready! Just follow the manual steps above to complete the setup!** 🎉
|
||||
|
||||
@@ -42,15 +42,16 @@ This guide walks you through setting up the complete booster opening flow, from
|
||||
├── CloseButton (Button)
|
||||
├── BottomRightContainer (SlotContainer)
|
||||
│ ├── Slot_0 (DraggableSlot)
|
||||
│ │ └── BoosterPack_0 (BoosterPackDraggable prefab instance)
|
||||
│ ├── Slot_1 (DraggableSlot)
|
||||
│ │ └── BoosterPack_1 (BoosterPackDraggable prefab instance)
|
||||
│ └── Slot_2 (DraggableSlot)
|
||||
│ └── BoosterPack_2 (BoosterPackDraggable prefab instance)
|
||||
├── CenterSlot (DraggableSlot)
|
||||
├── CardDisplayContainer (Empty RectTransform)
|
||||
└── BoosterInstances (Empty container)
|
||||
├── BoosterPack_0 (BoosterPackDraggable prefab)
|
||||
├── BoosterPack_1 (BoosterPackDraggable prefab)
|
||||
└── BoosterPack_2 (BoosterPackDraggable prefab)
|
||||
└── CardDisplayContainer (Empty RectTransform)
|
||||
```
|
||||
|
||||
> **💡 Tip:** Boosters are parented directly to their starting slots! This makes authoring easier and the hierarchy cleaner. No separate container needed.
|
||||
|
||||
---
|
||||
|
||||
@@ -65,11 +66,13 @@ This guide walks you through setting up the complete booster opening flow, from
|
||||
- Recommended position: X=800, Y=-400 (adjust for your canvas size)
|
||||
|
||||
**SlotContainer Settings:**
|
||||
- Layout Type: `Vertical`
|
||||
- Spacing: `120`
|
||||
- Center Slots: ✓
|
||||
- Layout Type: `Vertical` (or `Custom` for hand-authored positions - see custom_layout_guide.md)
|
||||
- Spacing: `120` (ignored if Layout Type = Custom)
|
||||
- Center Slots: ✓ (ignored if Layout Type = Custom)
|
||||
- Auto Register Children: ✓
|
||||
|
||||
> **💡 Tip:** Want artistic, scattered slot positions? Set Layout Type to `Custom` and manually position each slot in the Scene View. See `custom_layout_guide.md` for details!
|
||||
|
||||
**Child Slots (Slot_0, Slot_1, Slot_2):**
|
||||
- Add component: `DraggableSlot` to each
|
||||
- Size: 150x200 (adjust to your booster size)
|
||||
@@ -109,40 +112,65 @@ This guide walks you through setting up the complete booster opening flow, from
|
||||
|
||||
### **D. Booster Pack Instances**
|
||||
|
||||
You have two options: **Prefabs** or **Scene Instances**
|
||||
**Setup as Slot Children (Recommended):**
|
||||
|
||||
#### **Option 1: Using Prefabs (Recommended)**
|
||||
**Create a single BoosterPackPrefab with visual as a child:**
|
||||
|
||||
1. **Create BoosterPack Prefab:**
|
||||
```
|
||||
BoosterPackPrefab
|
||||
├── BoosterPackDraggable (component)
|
||||
├── Image (base - raycastTarget = false)
|
||||
└── Visual (BoosterPackVisual)
|
||||
├── Canvas
|
||||
├── CanvasGroup
|
||||
├── TiltParent (Transform)
|
||||
│ └── PackImage (Image - your booster sprite)
|
||||
├── ShakeParent (Transform)
|
||||
└── GlowEffect (ParticleSystem - optional)
|
||||
```
|
||||
**BoosterPackPrefab Structure:**
|
||||
```
|
||||
BoosterPackPrefab
|
||||
├── BoosterPackDraggable (component)
|
||||
├── CanvasGroup (component - for raycast control)
|
||||
└── Visual (child GameObject)
|
||||
├── Canvas (component - for z-order control)
|
||||
├── CanvasGroup (component - for alpha fading)
|
||||
├── BoosterPackVisual (component)
|
||||
├── ShakeParent (RectTransform - position/rotation punch effects)
|
||||
│ └── TiltParent (RectTransform - continuous smooth rotation)
|
||||
│ └── PackImage (Image - your booster sprite, raycastTarget = false)
|
||||
└── GlowEffect (ParticleSystem - optional)
|
||||
```
|
||||
|
||||
2. **BoosterPackDraggable Settings:**
|
||||
- Visual Prefab: Assign the Visual prefab
|
||||
- Can Open On Drop: ☐
|
||||
- Can Open On Double Click: ☐
|
||||
- **Can Tap To Open: ✓**
|
||||
- **Max Taps To Open: 3** (or your preference)
|
||||
**BoosterPackDraggable Settings:**
|
||||
- **Visual Prefab:** Leave empty (using child visual instead)
|
||||
- **Instantiate Visual:** ☐ unchecked (child visual is auto-detected)
|
||||
- Can Open On Drop: ☐
|
||||
- Can Open On Double Click: ☐
|
||||
- **Can Tap To Open: ✓**
|
||||
- **Max Taps To Open: 3**
|
||||
|
||||
3. **In Scene:**
|
||||
- Under `BoosterInstances` container, create 3 instances
|
||||
- Name them: `BoosterPack_0`, `BoosterPack_1`, `BoosterPack_2`
|
||||
- They will start inactive and be shown based on available count
|
||||
**BoosterPackVisual Settings (on the Visual child):**
|
||||
- Canvas: Auto-assigned or drag the Canvas component
|
||||
- Canvas Group: Auto-assigned or drag the CanvasGroup component
|
||||
- Tilt Parent: Drag `TiltParent`
|
||||
- Shake Parent: Drag `ShakeParent`
|
||||
- Pack Image: Drag `PackImage`
|
||||
- Pack Sprite: Assign your booster sprite asset
|
||||
- Glow Effect: Optional ParticleSystem
|
||||
- Glow Transform: Optional (for rotation)
|
||||
|
||||
#### **Option 2: Scene Instances**
|
||||
- Place 3 booster GameObjects directly in the scene
|
||||
- Configure as above
|
||||
- Set initial Active state to `false`
|
||||
> **📝 Simplified Approach!** The visual is now a **direct child** of the BoosterPackPrefab, making authoring much easier. The system auto-detects child visuals using `GetComponentInChildren<DraggableVisual>()`. This gives you:
|
||||
> - ✅ Full visual authoring control in the prefab
|
||||
> - ✅ See exactly what your booster looks like
|
||||
> - ✅ No separate prefab files to manage
|
||||
> - ✅ Simpler hierarchy and setup
|
||||
>
|
||||
> The visual still follows with smooth lerp/delay and all animations work the same!
|
||||
|
||||
> **📝 Note on Hierarchy:** ShakeParent and TiltParent are **nested RectTransforms** (ShakeParent → TiltParent → PackImage) so PackImage gets BOTH effects combined: shake (discrete position/rotation tweens) AND tilt (continuous smooth rotation). This nesting allows transform inheritance through Unity's parent-child chain.
|
||||
|
||||
> **📝 Note on Raycast Control:** The root BoosterPackPrefab uses CanvasGroup's `blocksRaycasts` for raycast toggling during drag. Visual children (PackImage, etc.) should have `raycastTarget = false` so clicks reach the root.
|
||||
|
||||
> **💡 Advanced Option:** If you prefer the old pattern (separate prefab files), you can still use it by assigning a prefab to `Visual Prefab` and checking `Instantiate Visual`. The system supports both patterns - it checks for a child visual first, then falls back to instantiation if configured.
|
||||
|
||||
3. **Add to Slots:**
|
||||
- Drag BoosterPackPrefab as child of `Slot_0` → Name it `BoosterPack_0`
|
||||
- Drag BoosterPackPrefab as child of `Slot_1` → Name it `BoosterPack_1`
|
||||
- Drag BoosterPackPrefab as child of `Slot_2` → Name it `BoosterPack_2`
|
||||
- Set each booster's **Active state to ☐ UNCHECKED** (starts inactive)
|
||||
- Position: (0, 0) local position (centered in slot)
|
||||
|
||||
> **💡 Why Parent to Slots?** The code calls `AssignToSlot()` which reparents anyway, so starting as a child of the slot makes authoring cleaner and more visual. You can see exactly where boosters will appear!
|
||||
|
||||
---
|
||||
|
||||
@@ -199,15 +227,17 @@ You have two options: **Prefabs** or **Scene Instances**
|
||||
|
||||
```
|
||||
BoosterVisual (BoosterPackVisual component)
|
||||
├── Canvas (sort order will be controlled at runtime)
|
||||
├── CanvasGroup (for fading)
|
||||
├── TiltParent (empty Transform for 3D tilt effect)
|
||||
│ ├── PackImage (Image - your booster pack sprite)
|
||||
│ └── FrameImage (Image - optional frame/border)
|
||||
├── ShakeParent (empty Transform for shake effects)
|
||||
├── Canvas (component - sort order controlled at runtime)
|
||||
├── CanvasGroup (component - for fading)
|
||||
├── ShakeParent (RectTransform - outer animation layer)
|
||||
│ └── TiltParent (RectTransform - inner animation layer)
|
||||
│ ├── PackImage (Image - your booster pack sprite)
|
||||
│ └── FrameImage (Image - optional frame/border)
|
||||
└── GlowEffect (Particle System - optional sparkles)
|
||||
```
|
||||
|
||||
> **💡 Animation Chain:** ShakeParent contains TiltParent, which contains the visuals. This nesting means PackImage gets BOTH shake (position/rotation punch) AND tilt (smooth continuous rotation) effects combined through Unity's transform hierarchy. Both are RectTransforms since this is UI.
|
||||
|
||||
### **Component Settings:**
|
||||
|
||||
**BoosterPackVisual:**
|
||||
|
||||
399
docs/custom_layout_guide.md
Normal file
399
docs/custom_layout_guide.md
Normal file
@@ -0,0 +1,399 @@
|
||||
# 🎨 SlotContainer Custom Layout Guide
|
||||
|
||||
## 📋 Overview
|
||||
|
||||
The `SlotContainer` has a **Custom** layout mode that's perfect for artistic, hand-authored slot positions! When you select `Custom`, the SlotContainer **doesn't automatically position your slots** - it lets you manually position them however you want.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 How Custom Layout Works
|
||||
|
||||
### **What Happens When Layout = Custom:**
|
||||
|
||||
Looking at the code:
|
||||
```csharp
|
||||
public void UpdateLayout()
|
||||
{
|
||||
if (layoutType == LayoutType.Custom)
|
||||
{
|
||||
OnLayoutChanged?.Invoke(); // Just fires the event
|
||||
return; // Doesn't reposition anything!
|
||||
}
|
||||
|
||||
// Other layouts (Horizontal, Vertical, Grid) reposition slots here...
|
||||
}
|
||||
```
|
||||
|
||||
**Key Point:** Custom layout means **"Don't touch my slot positions!"**
|
||||
|
||||
The SlotContainer still:
|
||||
- ✅ Registers your slots
|
||||
- ✅ Finds closest slot when dragging
|
||||
- ✅ Manages slot occupancy
|
||||
- ✅ Fires events
|
||||
|
||||
But it **does NOT:**
|
||||
- ❌ Automatically position slots
|
||||
- ❌ Apply spacing
|
||||
- ❌ Center slots
|
||||
- ❌ Use curves or grids
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Setting Up Custom Layout (Step-by-Step)
|
||||
|
||||
### **Method 1: Hand-Author in Scene (Recommended)**
|
||||
|
||||
This is the easiest and most visual approach:
|
||||
|
||||
1. **Create SlotContainer:**
|
||||
```
|
||||
BottomRightContainer
|
||||
└── [Add Component: SlotContainer]
|
||||
```
|
||||
|
||||
2. **Set Layout Type:**
|
||||
- Layout Type: `Custom`
|
||||
- Auto Register Children: ✓ (keep this checked)
|
||||
|
||||
3. **Create Slot Children:**
|
||||
```
|
||||
BottomRightContainer
|
||||
├── Slot_0 (DraggableSlot)
|
||||
├── Slot_1 (DraggableSlot)
|
||||
├── Slot_2 (DraggableSlot)
|
||||
└── Slot_3 (DraggableSlot)
|
||||
```
|
||||
|
||||
4. **Position Slots Manually in Scene View:**
|
||||
- Select `Slot_0`
|
||||
- Drag it to artistic position (e.g., X=-150, Y=200)
|
||||
- Select `Slot_1`
|
||||
- Drag it to artistic position (e.g., X=50, Y=150)
|
||||
- Select `Slot_2`
|
||||
- Drag it to artistic position (e.g., X=-200, Y=50)
|
||||
- Etc.
|
||||
|
||||
5. **Done!** Your slots stay exactly where you put them.
|
||||
|
||||
---
|
||||
|
||||
### **Method 2: Script Positions (For Procedural Scatter)**
|
||||
|
||||
If you want some randomness or code-controlled positions:
|
||||
|
||||
```csharp
|
||||
using UnityEngine;
|
||||
using UI.DragAndDrop.Core;
|
||||
|
||||
public class CustomSlotPositioner : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private SlotContainer slotContainer;
|
||||
[SerializeField] private Vector2[] handAuthoredPositions;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
PositionSlots();
|
||||
}
|
||||
|
||||
private void PositionSlots()
|
||||
{
|
||||
var slots = slotContainer.Slots;
|
||||
|
||||
for (int i = 0; i < slots.Count && i < handAuthoredPositions.Length; i++)
|
||||
{
|
||||
if (slots[i].RectTransform != null)
|
||||
{
|
||||
slots[i].RectTransform.anchoredPosition = handAuthoredPositions[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Then in Inspector:
|
||||
- Hand Authored Positions (Array):
|
||||
- Element 0: (-150, 200)
|
||||
- Element 1: (50, 150)
|
||||
- Element 2: (-200, 50)
|
||||
- Etc.
|
||||
|
||||
---
|
||||
|
||||
### **Method 3: Subscribe to OnLayoutChanged Event**
|
||||
|
||||
For advanced custom positioning logic:
|
||||
|
||||
```csharp
|
||||
using UnityEngine;
|
||||
using UI.DragAndDrop.Core;
|
||||
|
||||
public class ArtisticSlotLayout : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private SlotContainer slotContainer;
|
||||
[SerializeField] private float scatterRadius = 200f;
|
||||
[SerializeField] private bool useRandomSeed = true;
|
||||
[SerializeField] private int seed = 42;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (slotContainer != null)
|
||||
{
|
||||
slotContainer.OnLayoutChanged += ApplyCustomLayout;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (slotContainer != null)
|
||||
{
|
||||
slotContainer.OnLayoutChanged -= ApplyCustomLayout;
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyCustomLayout()
|
||||
{
|
||||
if (useRandomSeed)
|
||||
Random.InitState(seed);
|
||||
|
||||
var slots = slotContainer.Slots;
|
||||
|
||||
for (int i = 0; i < slots.Count; i++)
|
||||
{
|
||||
if (slots[i].RectTransform != null)
|
||||
{
|
||||
// Scattered circular layout
|
||||
float angle = Random.Range(0f, 360f);
|
||||
float distance = Random.Range(0f, scatterRadius);
|
||||
|
||||
float x = Mathf.Cos(angle * Mathf.Deg2Rad) * distance;
|
||||
float y = Mathf.Sin(angle * Mathf.Deg2Rad) * distance;
|
||||
|
||||
slots[i].RectTransform.anchoredPosition = new Vector2(x, y);
|
||||
|
||||
// Optional: Random rotation for extra artistic flair
|
||||
slots[i].RectTransform.rotation = Quaternion.Euler(0, 0, Random.Range(-15f, 15f));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Example: Artistic Scattered Boosters
|
||||
|
||||
### **Scenario:** 3 booster slots scattered artistically in bottom-right
|
||||
|
||||
**Setup:**
|
||||
```
|
||||
BottomRightContainer (SlotContainer - Custom Layout)
|
||||
├── Slot_0 (DraggableSlot)
|
||||
│ └── Position: (-180, 220)
|
||||
│ └── Rotation: (0, 0, -5) ← Slight tilt left
|
||||
├── Slot_1 (DraggableSlot)
|
||||
│ └── Position: (40, 180)
|
||||
│ └── Rotation: (0, 0, 8) ← Slight tilt right
|
||||
└── Slot_2 (DraggableSlot)
|
||||
└── Position: (-220, 80)
|
||||
└── Rotation: (0, 0, -3) ← Slight tilt left
|
||||
```
|
||||
|
||||
**Visual Result:**
|
||||
```
|
||||
[Slot_0] ← Tilted left, higher
|
||||
[Slot_1] ← Tilted right, middle
|
||||
[Slot_2] ← Tilted left, lower
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Custom Layout Inspector Settings
|
||||
|
||||
When you select **Custom** layout type, these settings are **ignored**:
|
||||
|
||||
- ❌ Spacing (not used)
|
||||
- ❌ Center Slots (not used)
|
||||
- ❌ Use Curve Layout (not used)
|
||||
- ❌ Position Curve (not used)
|
||||
- ❌ Curve Height (not used)
|
||||
|
||||
These settings **still work**:
|
||||
|
||||
- ✅ Auto Register Children (still registers your slots)
|
||||
- ✅ OnSlotAdded/OnSlotRemoved events (still fire)
|
||||
- ✅ OnLayoutChanged event (fires when UpdateLayout is called)
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Best Practices for Custom Layout
|
||||
|
||||
### **1. Use Scene View for Positioning**
|
||||
- Easiest and most visual
|
||||
- See results immediately
|
||||
- Adjust in real-time
|
||||
|
||||
### **2. Add Visual Guides**
|
||||
- Create a background image showing your intended layout
|
||||
- Position slots over the image
|
||||
- Delete/hide the guide after
|
||||
|
||||
### **3. Use Gizmos for Visualization**
|
||||
```csharp
|
||||
private void OnDrawGizmos()
|
||||
{
|
||||
if (slotContainer == null || slotContainer.Slots == null) return;
|
||||
|
||||
Gizmos.color = Color.yellow;
|
||||
|
||||
foreach (var slot in slotContainer.Slots)
|
||||
{
|
||||
if (slot != null)
|
||||
{
|
||||
Gizmos.DrawWireSphere(slot.transform.position, 50f);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### **4. Consider Spacing**
|
||||
- Even with artistic scatter, avoid overlapping slots
|
||||
- Leave enough space for hover/selection effects
|
||||
- Test with different screen sizes
|
||||
|
||||
### **5. Save Positions in Prefab**
|
||||
- Once you're happy with positions, save to prefab
|
||||
- Ensures consistency across scenes
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Combining Custom with Other Layouts
|
||||
|
||||
You can switch layout types at runtime:
|
||||
|
||||
```csharp
|
||||
public class DynamicLayoutSwitcher : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private SlotContainer slotContainer;
|
||||
|
||||
public void SwitchToScattered()
|
||||
{
|
||||
// Save current positions
|
||||
Vector2[] savedPositions = new Vector2[slotContainer.SlotCount];
|
||||
for (int i = 0; i < slotContainer.SlotCount; i++)
|
||||
{
|
||||
savedPositions[i] = slotContainer.GetSlotAtIndex(i).RectTransform.anchoredPosition;
|
||||
}
|
||||
|
||||
// Switch to custom
|
||||
// Note: You'd need to expose layoutType or use reflection
|
||||
// For now, this is just conceptual
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📋 Quick Setup Checklist
|
||||
|
||||
For your bottom-right booster slots:
|
||||
|
||||
1. **Create Container:**
|
||||
```
|
||||
BottomRightContainer
|
||||
└── Layout Type: Custom
|
||||
└── Auto Register Children: ✓
|
||||
```
|
||||
|
||||
2. **Create 3 Slot Children:**
|
||||
```
|
||||
Slot_0, Slot_1, Slot_2
|
||||
└── Each has DraggableSlot component
|
||||
```
|
||||
|
||||
3. **Position Each Slot:**
|
||||
- Use Scene View
|
||||
- Click and drag to artistic positions
|
||||
- Optional: Add slight rotation (Z-axis)
|
||||
|
||||
4. **Test:**
|
||||
- Drag boosters to slots
|
||||
- Verify they snap correctly
|
||||
- Adjust positions as needed
|
||||
|
||||
5. **Save to Prefab:**
|
||||
- Once happy, save BoosterOpeningPage prefab
|
||||
- Positions are preserved
|
||||
|
||||
---
|
||||
|
||||
## 💡 Creative Ideas
|
||||
|
||||
### **Scattered Stack:**
|
||||
```
|
||||
Slot_0: (-200, 250) Rotation: -8°
|
||||
Slot_1: (-180, 220) Rotation: 3°
|
||||
Slot_2: (-210, 195) Rotation: -5°
|
||||
```
|
||||
→ Looks like a messy pile of cards!
|
||||
|
||||
### **Arc Formation:**
|
||||
```
|
||||
Slot_0: (-180, 200) Rotation: -15°
|
||||
Slot_1: (0, 220) Rotation: 0°
|
||||
Slot_2: (180, 200) Rotation: 15°
|
||||
```
|
||||
→ Gentle arc, like cards in hand
|
||||
|
||||
### **Diagonal Cascade:**
|
||||
```
|
||||
Slot_0: (-150, 250) Rotation: -10°
|
||||
Slot_1: (-50, 180) Rotation: -5°
|
||||
Slot_2: (50, 110) Rotation: 0°
|
||||
```
|
||||
→ Diagonal waterfall effect
|
||||
|
||||
---
|
||||
|
||||
## 🐛 Troubleshooting Custom Layout
|
||||
|
||||
**Problem: Slots keep resetting position**
|
||||
→ Make sure Layout Type = `Custom`
|
||||
→ Check if something is calling `UpdateLayout()` with a different type
|
||||
|
||||
**Problem: Slots don't register**
|
||||
→ Ensure Auto Register Children = ✓
|
||||
→ Verify slots are direct children of SlotContainer
|
||||
|
||||
**Problem: Can't drag boosters to slots**
|
||||
→ Check DraggableSlot configuration (Filter By Type, etc.)
|
||||
→ Verify slots aren't locked
|
||||
|
||||
**Problem: Positions lost on scene reload**
|
||||
→ Save to prefab!
|
||||
→ Check if positions are being set in Awake/Start
|
||||
|
||||
---
|
||||
|
||||
## 📝 Summary
|
||||
|
||||
**Custom Layout = Full Manual Control!**
|
||||
|
||||
- ✅ Position slots anywhere you want
|
||||
- ✅ Add rotation for artistic flair
|
||||
- ✅ No automatic repositioning
|
||||
- ✅ Perfect for hand-authored layouts
|
||||
- ✅ Still gets all SlotContainer benefits (registration, finding, events)
|
||||
|
||||
**Recommended Workflow:**
|
||||
1. Set Layout Type = Custom
|
||||
2. Create slot children
|
||||
3. Position visually in Scene View
|
||||
4. Test drag-and-drop
|
||||
5. Adjust as needed
|
||||
6. Save to prefab
|
||||
|
||||
---
|
||||
|
||||
🎨 **Now go create some beautiful, artistic slot layouts!** 🎨
|
||||
|
||||
2031
docs/test_log.txt
Normal file
2031
docs/test_log.txt
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user