MVP of the plane throwing game #77

Merged
tschesky merged 7 commits from valentines into main 2025-12-07 19:36:58 +00:00
128 changed files with 15474 additions and 1589 deletions
Showing only changes of commit 6754664a34 - Show all commits

View File

@@ -1,426 +0,0 @@
# Airplane Selection & Ability System - COMPLETE IMPLEMENTATION
**Date**: December 6, 2025
**Status**: ✅ **100% CODE COMPLETE** - Ready for Unity Setup
---
## ✅ ALL PHASES COMPLETE
### **Phase 1: Data Foundation** ✅
- `AirplaneAbilityType.cs` - Enum for ability types
- `BaseAirplaneAbility.cs` - Abstract base class
- `JetAbility.cs` - Hold to fly straight
- `BobbingAbility.cs` - Tap to jump
- `DropAbility.cs` - Swipe to drop
- `AirplaneTypeData.cs` - ScriptableObject config
### **Phase 2: Controller Extensions** ✅
- `AirplaneController.cs` - Full ability integration
### **Phase 3: UI Components** ✅
- `AirplaneAbilityButton.cs` - With proper InputManager integration
- `AirplaneSelectionUI.cs` - Pre-game selection
### **Phase 4: Launch Controller** ✅
- `AirplaneLaunchController.cs` - Pre-spawn support
### **Phase 5: Game Manager Integration** ✅
- `AirplaneGameManager.cs` - Complete game flow integration
- `AirplaneGameState.cs` - Added AirplaneSelection state
### **Phase 6: Settings Integration** ✅
- `IAirplaneSettings` - Added DefaultAirplaneType property
- `AirplaneSettings.cs` - Implemented default type field
---
## 🎮 COMPLETE GAME FLOW
```
1. Game Start
2. AIRPLANE SELECTION STATE (NEW)
- Show AirplaneSelectionUI
- Player selects airplane type (Jet/Bobbing/Drop)
- Confirm selection
- Store selected type
3. Intro Sequence
- People greet
- Camera transitions
4. Setup First Person
- Get person's target
- Initialize spawn manager
5. ENTER AIMING STATE (UPDATED)
- Spawn selected airplane at slingshot (NEW)
- Airplane visible before launch (NEW)
- Show target UI
- Enable launch controller
6. AIRPLANE LAUNCHED (UPDATED)
- Show ability button with airplane's ability (NEW)
- Camera follows airplane
- Spawn manager tracks
7. FLYING STATE (NEW ABILITIES)
- Player can activate special ability (NEW)
* Jet: Hold button to fly straight
* Bobbing: Tap to jump upward
* Drop: Tap to drop down
- Cooldown management (NEW)
8. EVALUATE RESULT (UPDATED)
- Hide ability button (NEW)
- Stop tracking
- Cleanup based on success/failure
9. Continue/Game Over
```
---
## 📋 IN-ENGINE SETUP STEPS
### **STEP 1: Create Ability ScriptableObjects**
In Unity Project window:
1. **Create JetAbility**:
- Right-click → Create → AppleHills → Airplane → Abilities → Jet
- Name: `JetAbility`
- Configure:
* Ability Name: "Jet Boost"
* Cooldown Duration: 5.0
* Jet Speed: 15.0
* Jet Angle: 0
* Assign ability icon sprite
2. **Create BobbingAbility**:
- Right-click → Create → AppleHills → Airplane → Abilities → Bobbing
- Name: `BobbingAbility`
- Configure:
* Ability Name: "Air Hop"
* Cooldown Duration: 3.0
* Bob Jump Force: 10.0
* Speed Reduction: 0.7 (70%)
* Assign ability icon sprite
3. **Create DropAbility**:
- Right-click → Create → AppleHills → Airplane → Abilities → Drop
- Name: `DropAbility`
- Configure:
* Ability Name: "Dive Bomb"
* Cooldown Duration: 4.0
* Drop Force: 20.0
* Drop Distance: 5.0
* Zero Horizontal Velocity: ✓
* Assign ability icon sprite
### **STEP 2: Create Airplane Type Assets**
1. **Create JetPlaneType**:
- Right-click → Create → AppleHills → Airplane → Airplane Type
- Name: `JetPlaneType`
- Configure:
* Type ID: "jet"
* Display Name: "Jet Plane"
* Prefab: Assign jet airplane prefab
* Preview Sprite: Assign preview image
* Ability: Assign `JetAbility` asset
* Optional physics overrides
2. **Create BobbingPlaneType**:
- Right-click → Create → AppleHills → Airplane → Airplane Type
- Name: `BobbingPlaneType`
- Configure:
* Type ID: "bobbing"
* Display Name: "Bobbing Plane"
* Prefab: Assign bobbing airplane prefab
* Preview Sprite: Assign preview image
* Ability: Assign `BobbingAbility` asset
* Optional physics overrides
3. **Create DropPlaneType**:
- Right-click → Create → AppleHills → Airplane → Airplane Type
- Name: `DropPlaneType`
- Configure:
* Type ID: "drop"
* Display Name: "Drop Plane"
* Prefab: Assign drop airplane prefab
* Preview Sprite: Assign preview image
* Ability: Assign `DropAbility` asset
* Optional physics overrides
### **STEP 3: Create Selection UI Hierarchy**
In Scene Hierarchy:
1. **Find or create Canvas**: `AirplaneMinigameCanvas`
2. **Create Selection Panel**:
```
AirplaneSelectionPanel (GameObject + AirplaneSelectionUI component)
├── Background (Image - dark overlay)
├── TitleText (TextMeshPro: "Choose Your Airplane")
├── ButtonsContainer (Horizontal Layout Group)
│ ├── JetPlaneButton (Button)
│ │ ├── Icon (Image)
│ │ ├── NameText (TextMeshPro: "Jet Plane")
│ │ └── AbilityIcon (Image - small)
│ ├── BobbingPlaneButton (Button)
│ │ └── (same structure)
│ └── DropPlaneButton (Button)
│ └── (same structure)
└── ConfirmButton (Button: "Confirm Selection")
```
3. **Configure AirplaneSelectionUI component**:
- Drag buttons to references:
* Jet Plane Button → `jetPlaneButton`
* Bobbing Plane Button → `bobbingPlaneButton`
* Drop Plane Button → `dropPlaneButton`
* Confirm Button → `confirmButton`
- Assign airplane types:
* `JetPlaneType` → `jetPlaneType`
* `BobbingPlaneType` → `bobbingPlaneType`
* `DropPlaneType` → `dropPlaneType`
- Set colors:
* Selected Color: Yellow
* Normal Color: White
4. **Set panel inactive by default** (checked in Inspector)
### **STEP 4: Create Ability Button UI**
In Scene Hierarchy under GameplayUI:
```
AbilityButton (GameObject + AirplaneAbilityButton component)
├── Background (Image - circular button background)
├── AbilityIcon (Image - dynamically set)
├── CooldownFill (Image)
│ └── Fill Type: Radial 360
│ └── Clockwise: ✓
│ └── Fill Origin: Top
└── CooldownText (TextMeshPro - optional: "3.2s")
```
**Configure AirplaneAbilityButton component**:
- Button: Assign Button component
- Ability Icon: Assign icon Image
- Cooldown Fill: Assign fill Image
- Cooldown Text: Assign TextMeshPro (optional)
- Colors:
* Ready Color: White
* Cooldown Color: Gray
* Active Color: Yellow
**Position**: Bottom-right corner, accessible for thumb
**Set inactive by default** (checked in Inspector)
### **STEP 5: Configure AirplaneGameManager**
Select AirplaneGameManager GameObject:
1. **Assign new references**:
- Selection UI: Drag `AirplaneSelectionPanel`
- Ability Button: Drag `AbilityButton`
2. **Verify existing references still assigned**:
- Person Queue
- Camera Manager
- Launch Controller
- Target Validator
- Spawn Manager
### **STEP 6: Update AirplaneSettings Asset**
Find your `AirplaneSettings` ScriptableObject:
1. **New section appears**: "Airplane Types"
2. **Assign default type**:
- Default Airplane Type: Assign `JetPlaneType` (or your preferred default)
This is used as fallback if selection UI is missing.
### **STEP 7: Test in Play Mode**
**Test Checklist**:
#### Selection UI:
- [ ] Selection panel appears on game start
- [ ] All three buttons visible and clickable
- [ ] Clicking button highlights it (yellow)
- [ ] Confirm button enables after selection
- [ ] Clicking confirm proceeds to game
- [ ] Selected airplane spawns at slingshot
#### Airplane Pre-Spawn:
- [ ] Selected airplane visible at slingshot
- [ ] Airplane stays in place (kinematic)
- [ ] Trajectory preview works
- [ ] Airplane launches correctly
#### Jet Ability (Hold):
- [ ] Ability button appears after launch
- [ ] Shows jet icon
- [ ] Tap and hold activates ability
- [ ] Airplane flies straight while held
- [ ] Releasing stops ability
- [ ] Cooldown fills from 1→0
- [ ] Button grays out during cooldown
- [ ] Can use again after cooldown
#### Bobbing Ability (Tap):
- [ ] Ability button appears after launch
- [ ] Shows bobbing icon
- [ ] Tap activates instantly
- [ ] Airplane jumps upward
- [ ] Speed reduces
- [ ] Cooldown starts immediately
- [ ] Can use multiple times
#### Drop Ability (Tap):
- [ ] Ability button appears after launch
- [ ] Shows drop icon
- [ ] Tap activates instantly
- [ ] Airplane drops straight down
- [ ] Stops after configured distance
- [ ] Cooldown starts after drop
- [ ] Can use again after cooldown
#### Integration:
- [ ] Ability button hides after turn ends
- [ ] Works with retry system (same airplane)
- [ ] Works with person shuffle (new airplane)
- [ ] No errors in console
- [ ] Performance is good
---
## 🎨 VISUAL/AUDIO POLISH (Optional)
### Recommended Enhancements:
1. **Selection UI Animation**:
- Fade in/out transitions
- Button hover effects
- Selection sound effects
2. **Ability VFX**:
- Jet: Trail particle effect
- Bobbing: Puff of air particles
- Drop: Speed lines downward
3. **Ability SFX**:
- Jet: "Whoooosh" sustained sound
- Bobbing: "Boing" spring sound
- Drop: "Dive bomb" whistle
4. **Button Feedback**:
- Haptic feedback on activation
- Button press animation
- Cooldown tick sound
---
## 🔧 TROUBLESHOOTING
### Issue: "Cannot resolve symbol 'Abilities'"
**Solution**: Unity needs to recompile scripts. Wait for compilation to finish, or reimport scripts folder.
### Issue: Selection UI doesn't show
**Solution**:
1. Check `AirplaneGameManager.selectionUI` is assigned
2. Verify panel starts inactive
3. Check game flow starts with `StartGame()`
### Issue: Ability button doesn't appear
**Solution**:
1. Check `AirplaneGameManager.abilityButton` is assigned
2. Verify button starts inactive
3. Ensure airplane has ability (check AirplaneTypeData)
4. Check console for errors
### Issue: Hold doesn't work for Jet ability
**Solution**:
1. Verify InputManager instance exists
2. Check button implements ITouchInputConsumer
3. Test with mouse (click and hold) first
4. Check console for registration messages
### Issue: Airplane doesn't spawn at slingshot
**Solution**:
1. Check `_selectedAirplaneType` is set
2. Verify AirplaneTypeData has prefab assigned
3. Check launch controller has launch anchor
4. Look for errors in console
---
## 📊 ARCHITECTURE SUMMARY
**Design Patterns**:
- ✅ Strategy Pattern (abilities)
- ✅ State Machine (game states)
- ✅ Observer Pattern (events)
- ✅ Singleton (managers)
- ✅ Template Method (abstract Execute)
**SOLID Principles**:
- ✅ Single Responsibility
- ✅ Open/Closed
- ✅ Liskov Substitution
- ✅ Interface Segregation
- ✅ Dependency Inversion
**Input System**:
- ✅ Uses project's InputManager
- ✅ Implements ITouchInputConsumer
- ✅ Override consumer registration
- ✅ No legacy Input API
---
## 🚀 EXTENSIBILITY
### Adding New Airplane Type:
1. Create new ability class extending `BaseAirplaneAbility`
2. Override `Execute()` method
3. Create ability ScriptableObject
4. Create AirplaneTypeData asset
5. Add button to selection UI
6. Assign references
**No code changes required!**
### Adding New Ability Property:
1. Add field to ability class
2. Configure in Inspector
3. Use in `Execute()` method
**Example**: Add "boost duration" to JetAbility
```csharp
[SerializeField] private float boostDuration = 3f;
```
---
## ✅ IMPLEMENTATION COMPLETE
**Total Files Created**: 6
**Total Files Modified**: 9
**Total Lines of Code**: ~1,500
**Compilation Errors**: 0
**Warnings**: 5 (naming conventions only)
**Status**: Ready for Unity asset creation and testing!
**Next Steps**: Follow in-engine setup steps above to complete integration.

View File

@@ -1,463 +0,0 @@
# Airplane Selection & Abilities - SETTINGS-BASED IMPLEMENTATION
**Date**: December 6, 2025
**Status**: ✅ **COMPLETE** - Pure Settings Configuration
---
## 🎯 SIMPLIFIED ARCHITECTURE
**NO ScriptableObject assets needed!** Everything configured in `AirplaneSettings`.
### Key Changes from Previous Design:
- ❌ No `AirplaneTypeData` ScriptableObjects to create
- ❌ No ability ScriptableObjects to create
- ✅ All configuration in `AirplaneSettings` asset
- ✅ Abilities created from settings at runtime
- ✅ Simple enum selection (Jet/Bobbing/Drop)
---
## 📋 IN-ENGINE SETUP (3 SIMPLE STEPS)
### **STEP 1: Configure Settings (5 minutes)**
Open `Tools > Settings > Airplane Settings`
You'll see **collapsible sections** for each airplane type:
#### **Jet Plane Configuration**
```
Display Name: "Jet Plane"
Prefab: [Assign jet airplane prefab]
Preview Sprite: [Assign preview image]
Ability Type: Jet
Override Mass: □ (optional)
Override Gravity Scale: □ (optional)
Override Drag: □ (optional)
Jet Ability:
├─ Ability Name: "Jet Boost"
├─ Ability Icon: [Assign icon sprite]
├─ Cooldown Duration: 5.0
├─ Jet Speed: 15.0
└─ Jet Angle: 0
```
#### **Bobbing Plane Configuration**
```
Display Name: "Bobbing Plane"
Prefab: [Assign bobbing airplane prefab]
Preview Sprite: [Assign preview image]
Ability Type: Bobbing
Bobbing Ability:
├─ Ability Name: "Air Hop"
├─ Ability Icon: [Assign icon sprite]
├─ Cooldown Duration: 3.0
└─ Bob Force: (7, 10)
• X = Forward force (horizontal momentum)
• Y = Upward force (vertical lift)
```
**How It Works:** Applies diagonal impulse force using Vector2 configuration. X controls forward momentum, Y controls upward lift. This gives direct control over the exact force applied in both directions.
**Examples:**
- `(0, 15)` - Pure vertical jump
- `(10, 10)` - 45° diagonal boost
- `(12, 5)` - More forward than upward
#### **Drop Plane Configuration**
```
Display Name: "Drop Plane"
Prefab: [Assign drop airplane prefab]
Preview Sprite: [Assign preview image]
Ability Type: Drop
Drop Ability:
├─ Ability Name: "Dive Bomb"
├─ Ability Icon: [Assign icon sprite]
├─ Cooldown Duration: 4.0
├─ Drop Force: 20.0
├─ Drop Distance: 5.0
└─ Zero Horizontal Velocity: ☑
```
#### **Default Selection**
```
Default Airplane Type: Jet
```
### **STEP 2: Build UI (10 minutes)**
#### Selection Panel:
```
AirplaneSelectionPanel (+ AirplaneSelectionUI component)
├── TitleText ("Choose Your Airplane")
├── JetPlaneButton
├── BobbingPlaneButton
├── DropPlaneButton
└── ConfirmButton
```
**Component Configuration:**
- Jet Plane Button → Assign button
- Bobbing Plane Button → Assign button
- Drop Plane Button → Assign button
- Confirm Button → Assign button
- Selected Color: Yellow
- Normal Color: White
- ☑ Start inactive
**NO airplane type assets to assign!**
#### Ability Button:
```
AbilityButton (+ AirplaneAbilityButton component)
├── Background (Image)
├── AbilityIcon (Image)
├── CooldownFill (Image - Radial 360)
└── CooldownText (TextMeshPro)
```
**Component Configuration:**
- Assign Button, Icon, Fill, Text references
- Ready: White, Cooldown: Gray, Active: Yellow
- ☑ Start inactive
### **STEP 3: Wire GameManager (2 minutes)**
In `AirplaneGameManager`:
- Selection UI → Assign AirplaneSelectionPanel
- Ability Button → Assign AbilityButton
**Done!**
---
## 🎮 HOW IT WORKS
### Runtime Flow:
```
1. Game Start
2. Show Selection UI
- Player clicks Jet/Bobbing/Drop button
- Confirm selection
3. System loads config from settings
- Gets AirplaneTypeConfig for selected type
- Gets ability config (Jet/Bobbing/Drop)
4. AbilityFactory creates ability instance
- new JetAbility(name, icon, cooldown, speed, angle)
- Ability initialized with airplane reference
5. Airplane spawns at slingshot
- Prefab from config
- Physics overrides from config
- Ability attached
6. Player launches
- Ability button shows with icon from config
- Cooldown system active
7. Player uses ability
- Jet: Hold to fly straight
- Bobbing: Tap to jump
- Drop: Tap to dive
```
### Code Architecture:
```
AirplaneSettings (ScriptableObject)
├─ JetPlaneConfig (serializable class)
├─ JetAbilityConfig (serializable class)
├─ BobbingPlaneConfig (serializable class)
├─ BobbingAbilityConfig (serializable class)
├─ DropPlaneConfig (serializable class)
└─ DropAbilityConfig (serializable class)
AbilityFactory (static)
└─ CreateAbility(type, settings) → BaseAirplaneAbility
├─ Jet → new JetAbility(...)
├─ Bobbing → new BobbingAbility(...)
└─ Drop → new DropAbility(...)
BaseAirplaneAbility (abstract class)
├─ JetAbility
├─ BobbingAbility
└─ DropAbility
```
---
## 📊 COMPARISON
### OLD Design (ScriptableObject-based):
```
Steps to add new airplane:
1. Create ability ScriptableObject asset
2. Configure ability in Inspector
3. Create airplane type ScriptableObject asset
4. Link ability to airplane type
5. Assign airplane type to selection UI
6. Test
Assets created: 2 per airplane type
```
### NEW Design (Settings-based):
```
Steps to add new airplane:
1. Open Settings
2. Configure airplane + ability
3. Test
Assets created: 0 (all in settings!)
```
**Result**: 66% fewer steps, 100% fewer assets! 🎉
---
## 🔧 EXTENDING THE SYSTEM
### Adding a 4th Airplane Type:
1. **Add enum value**:
```csharp
// AirplaneAbilityType.cs
public enum AirplaneAbilityType
{
None,
Jet,
Bobbing,
Drop,
Glider // NEW
}
```
2. **Create ability config class**:
```csharp
// AirplaneAbilityConfig.cs
[System.Serializable]
public class GliderAbilityConfig
{
public string abilityName = "Glide";
public Sprite abilityIcon;
public float cooldownDuration = 2f;
public float glideDuration = 5f;
// ... other fields
}
```
3. **Create ability class**:
```csharp
// GliderAbility.cs
public class GliderAbility : BaseAirplaneAbility
{
public GliderAbility(string name, Sprite icon, float cooldown, float duration)
: base(name, icon, cooldown)
{
// ...
}
public override void Execute()
{
// Implementation
}
}
```
4. **Add to settings**:
```csharp
// AirplaneSettings.cs
[Header("Glider Plane")]
[SerializeField] private Data.AirplaneTypeConfig gliderPlaneConfig;
[SerializeField] private Data.GliderAbilityConfig gliderAbilityConfig;
```
5. **Update factory**:
```csharp
// AbilityFactory.cs
case AirplaneAbilityType.Glider => CreateGliderAbility(settings),
```
6. **Add UI button**:
```
Add gliderPlaneButton to selection UI
```
**Done!** No ScriptableObject assets needed.
---
## ✅ BENEFITS
### For Designers:
**Single location** - All config in one settings file
**No asset management** - No separate files to track
**Collapsible sections** - Clean Inspector organization
**Fast iteration** - Change values, play test immediately
**No references to wire** - Settings accessed by code
### For Developers:
**Less boilerplate** - No CreateAssetMenu attributes
**Runtime creation** - Abilities instantiated from settings
**Type-safe** - Enum-based selection
**Factory pattern** - Clean ability creation
**Easy extension** - Add new types with minimal code
### For Players:
**Same experience** - Gameplay unchanged
**Faster loading** - No asset references to load
**Consistent behavior** - All from one source of truth
---
## 📝 FILES CREATED/MODIFIED
### New Files:
1. `AirplaneAbilityConfig.cs` - Config classes for abilities
2. `AbilityFactory.cs` - Factory for creating abilities
### Modified Files:
1. `BaseAirplaneAbility.cs` - No longer ScriptableObject
2. `JetAbility.cs` - Constructor-based
3. `BobbingAbility.cs` - Constructor-based
4. `DropAbility.cs` - Constructor-based
5. `AirplaneSettings.cs` - Added all airplane/ability configs
6. `IAirplaneSettings.cs` - Updated interface
7. `AirplaneController.cs` - Uses factory to create abilities
8. `AirplaneLaunchController.cs` - Works with enum types
9. `AirplaneSelectionUI.cs` - Works with enum types
10. `AirplaneGameManager.cs` - Works with enum types
### Deleted Files:
1. `AirplaneTypeData.cs` - No longer needed!
---
## 🧪 TESTING
Same as before, but **no assets to create first**!
1. ▶️ Play
2. Selection UI shows
3. Click airplane type
4. Confirm
5. Airplane spawns at slingshot
6. Launch and use ability
7. Cooldown works
8. ✅ Success!
---
## 🚀 MIGRATION FROM OLD SYSTEM
If you had the ScriptableObject-based system:
1. **Note your configurations** from existing assets
2. **Delete** old ScriptableObject assets:
- Delete JetAbility.asset
- Delete BobbingAbility.asset
- Delete DropAbility.asset
- Delete JetPlaneType.asset
- Delete BobbingPlaneType.asset
- Delete DropPlaneType.asset
3. **Open Settings** and enter values from step 1
4. **Update UI references**:
- Selection UI no longer needs type assets
- Remove those fields (now just buttons)
5. **Test** - Should work immediately!
---
## 💡 ADVANCED TIPS
### Inspector Organization:
Use `[Header]` attributes to create collapsible sections:
```csharp
[Header("=== AIRPLANE TYPES ===")]
[Header("Jet Plane")]
// ... jet config fields
[Header("Bobbing Plane")]
// ... bobbing config fields
```
### Default Values:
Initialize configs with sensible defaults:
```csharp
private Data.JetAbilityConfig jetAbilityConfig = new Data.JetAbilityConfig
{
abilityName = "Jet Boost",
cooldownDuration = 5f,
jetSpeed = 15f
};
```
### Validation:
Add validation in `OnValidate()`:
```csharp
private void OnValidate()
{
if (jetAbilityConfig.cooldownDuration < 0f)
jetAbilityConfig.cooldownDuration = 0f;
}
```
---
## ✅ FINAL CHECKLIST
Configuration:
- [ ] Jet plane config complete
- [ ] Jet ability config complete
- [ ] Bobbing plane config complete
- [ ] Bobbing ability config complete
- [ ] Drop plane config complete
- [ ] Drop ability config complete
- [ ] Default type selected
- [ ] All sprites assigned
UI Setup:
- [ ] Selection panel created
- [ ] Three buttons assigned
- [ ] Ability button created
- [ ] Button components assigned
Integration:
- [ ] GameManager references assigned
- [ ] Settings saved
- [ ] No compilation errors
Testing:
- [ ] Selection works
- [ ] Spawning works
- [ ] Jet ability works (hold)
- [ ] Bobbing ability works (tap)
- [ ] Drop ability works (tap)
- [ ] Cooldowns work
- [ ] No console errors
**When all checked → Settings-based system complete!** 🎉
---
## 📖 SUMMARY
**Converted from**: ScriptableObject asset-based system
**Converted to**: Pure settings-based system
**Assets eliminated**: 6 (3 abilities + 3 types)
**Setup time reduced**: ~15 minutes saved
**Maintenance complexity**: Significantly reduced
**Extensibility**: Improved (add types faster)
**The system is now designer-friendly, maintainable, and requires NO external asset creation!**

View File

@@ -1,211 +0,0 @@
# Airplane Abilities - Unity Setup Quick Reference
**⚡ Fast setup guide for in-engine configuration**
---
## 🎯 7 Steps to Complete Setup
### **1⃣ CREATE ABILITIES** (3 assets)
```
Project Window → Right-Click → Create → AppleHills → Airplane → Abilities
```
| Asset | Name | Cooldown | Key Values |
|-------|------|----------|------------|
| Jet | `JetAbility` | 5s | Speed: 15, Angle: 0 |
| Bobbing | `BobbingAbility` | 3s | Jump: 10, Speed Reduction: 0.7 |
| Drop | `DropAbility` | 4s | Force: 20, Distance: 5 |
✅ Assign icon sprites to each
---
### **2⃣ CREATE AIRPLANE TYPES** (3 assets)
```
Project Window → Right-Click → Create → AppleHills → Airplane → Airplane Type
```
| Type | Name | Display Name | Ability |
|------|------|--------------|---------|
| Jet | `JetPlaneType` | "Jet Plane" | JetAbility |
| Bobbing | `BobbingPlaneType` | "Bobbing Plane" | BobbingAbility |
| Drop | `DropPlaneType` | "Drop Plane" | DropAbility |
✅ Assign prefabs and preview sprites
---
### **3⃣ BUILD SELECTION UI**
**Hierarchy Path**: `Canvas/AirplaneSelectionPanel`
```
AirplaneSelectionPanel (+ AirplaneSelectionUI component)
├── TitleText ("Choose Your Airplane")
├── JetPlaneButton
├── BobbingPlaneButton
├── DropPlaneButton
└── ConfirmButton
```
**Component Setup**:
- Assign 3 button references
- Assign 3 airplane type assets
- Selected Color: Yellow
- Normal Color: White
-**Start inactive**
---
### **4⃣ BUILD ABILITY BUTTON**
**Hierarchy Path**: `Canvas/GameplayUI/AbilityButton`
```
AbilityButton (+ AirplaneAbilityButton component)
├── Background (Image)
├── AbilityIcon (Image - dynamic)
├── CooldownFill (Image - Radial 360)
└── CooldownText (TextMeshPro - optional)
```
**Component Setup**:
- Assign Button, Icon, Fill, Text
- Ready: White, Cooldown: Gray, Active: Yellow
-**Start inactive**
---
### **5⃣ WIRE GAME MANAGER**
**GameObject**: `AirplaneGameManager`
**New References**:
- Selection UI → AirplaneSelectionPanel
- Ability Button → AbilityButton
✅ Verify existing references still assigned
---
### **6⃣ UPDATE SETTINGS**
**Asset**: `AirplaneSettings` (existing)
**New Field**:
- Default Airplane Type → Assign `JetPlaneType`
---
### **7⃣ TEST IN PLAY MODE**
**Quick Test**:
1. ▶️ Play
2. Selection UI appears
3. Click airplane → Confirm
4. Airplane spawns at slingshot
5. Launch and use ability
6. Button shows cooldown
**If all works, you're done!**
---
## 🎨 UI LAYOUT TIPS
### Selection Panel Position:
- Center screen
- Width: 80% of screen
- Background: Semi-transparent dark
- Buttons: Horizontal layout, equal spacing
### Ability Button Position:
- Bottom-right corner
- Size: 80x80 pixels
- Margin: 20px from edges
- Z-order: On top of everything
---
## ⚡ FAST TESTING
### Test Jet (Hold):
1. Launch airplane
2. **Click and hold** ability button
3. Airplane flies straight
4. **Release** → Stops
### Test Bobbing (Tap):
1. Launch airplane
2. **Tap** ability button
3. Airplane jumps up
4. Wait for cooldown
5. Tap again
### Test Drop (Tap):
1. Launch airplane
2. **Tap** ability button
3. Airplane drops down
4. Stops after distance
---
## 🐛 COMMON ISSUES
| Problem | Fix |
|---------|-----|
| Selection UI doesn't show | Check it's assigned in GameManager |
| Button doesn't appear | Check airplane has ability assigned |
| Hold doesn't work | Check InputManager exists in scene |
| Airplane doesn't spawn | Check TypeData has prefab assigned |
| Cooldown doesn't show | Check Fill image is assigned and Radial 360 |
---
## 📱 MOBILE TESTING
1. Build to device
2. Test touch hold (Jet ability)
3. Test tap (Bobbing/Drop)
4. Verify button size is thumb-friendly
5. Check cooldown is visible
---
## ✅ COMPLETE CHECKLIST
**Settings:**
- [ ] Configured all 3 airplane types in settings
- [ ] Assigned all prefabs and sprites
- [ ] Set default airplane type
**UI:**
- [ ] Built selection UI panel
- [ ] Built ability button UI
- [ ] Assigned button references (NO type assets!)
- [ ] Assigned GameManager references
**Testing:**
- [ ] Selection UI appears and works
- [ ] Tested Jet ability (hold)
- [ ] Tested Bobbing ability (tap)
- [ ] Tested Drop ability (tap)
- [ ] All cooldowns work
- [ ] No console errors
**When all checked → Ship it! 🚀**
---
## 🎉 ADVANTAGES
**NO ScriptableObject assets to create!**
**Everything in one settings file**
**Faster setup** (3 steps vs 7)
**Easier to maintain**
**Collapsible Inspector sections**
**Runtime ability creation from config**

View File

@@ -1 +0,0 @@


View File

@@ -1,298 +0,0 @@
# Airplane Minigame - Implementation Summary
## ✅ IMPLEMENTATION COMPLETE
All requested changes have been successfully implemented:
---
## 🔄 Changes Made
### 1. ✅ Physics-Based Airplane Movement
**File**: `AirplaneController.cs`
**Changes**:
- Converted from kinematic to **dynamic Rigidbody2D**
- Replaced manual velocity updates with **AddForce(impulse)** on launch
- Removed manual gravity calculations (Unity physics handles it)
- Changed `FlightUpdateCoroutine``FlightMonitorCoroutine` (only handles rotation & timeout)
- Smoother, less choppy movement using Unity's physics engine
**Benefits**:
- Natural arc trajectory
- No more manual frame-by-frame velocity updates
- Consistent with trajectory preview calculations
- Less code, better performance
---
### 2. ✅ Person Component Created
**File**: `Person.cs` (NEW)
**Features**:
- MonoBehaviour component with person data (name, target)
- Three awaitable coroutines:
- `OnHello()` - First introduction
- `OnTargetHit()` - Success reaction
- `OnTargetMissed()` - Failure reaction
- Optional visual references (sprite, animator)
- Configurable timing durations
- Auto-validates data on awake
**Usage**: Attach to GameObjects in scene, drag references to PersonQueue
---
### 3. ✅ PersonQueue Refactored
**File**: `PersonQueue.cs`
**Changes**:
- Replaced `List<PersonData>` with **`List<Person>`** component references
- Added `RemoveCurrentPerson()` method
- Added **transition control methods**:
- `ShowFirstPerson(Person)` - Game start introduction
- `TransitionToNextPerson(Person prev, Person next, bool hit)` - Handle reactions & shuffle
- `ShuffleTransition(Vector3)` - Animated position shuffle
- Queue now **owns** all person-related timing and visuals
- Delegates control back to GameManager when done
**Flow on Success**:
1. Call previous person's `OnTargetHit()`
2. Wait for celebration
3. Remove person from queue
4. Shuffle remaining people left (animated)
5. Call next person's `OnHello()`
6. Return control to GameManager
**Flow on Failure**:
1. Call previous person's `OnTargetMissed()`
2. Wait for reaction
3. Keep person in queue (no shuffle)
4. Call next person's `OnHello()`
5. Return control to GameManager
---
### 4. ✅ GameManager Integration
**File**: `AirplaneGameManager.cs`
**Changes**:
- Updated state variables to use `Person` instead of `PersonData`
- Added `_previousPerson` tracking
- Added `_lastShotHit` flag
- Updated event signatures to use `Person`
- Modified `SetupNextPerson()` to delegate to PersonQueue:
```csharp
if (_previousPerson == null)
yield return personQueue.ShowFirstPerson(_currentPerson);
else
yield return personQueue.TransitionToNextPerson(_previousPerson, _currentPerson, _lastShotHit);
```
- Set `_lastShotHit` in all result handlers
**Result**: Clean separation - GameManager orchestrates, PersonQueue handles visuals/timing
---
### 5. ✅ PersonData.cs Status
**Status**: Still exists but **not used in queue**
**Options**:
- Keep as data-only struct for potential future use
- Delete entirely (Person component replaces it)
**Recommendation**: Can be safely deleted - Person component is superior
---
## 📊 Code Quality
### Compilation Status
- ✅ AirplaneController.cs - No errors
- ✅ Person.cs - Only minor warnings (string triggers, redundant initializers)
- ✅ PersonQueue.cs - Only minor warnings (unused parameter, redundant initializer)
- ✅ AirplaneGameManager.cs - Some false positives from IDE cache, actual compilation should work
- ✅ AirplaneLaunchController.cs - No errors
**Total**: Production-ready with only minor style warnings
---
## 🎮 How It Works Now
### Game Flow
```
1. Intro Sequence (1s)
2. ShowFirstPerson()
├─ Person.OnHello()
└─ Wait for completion
3. Setup Aiming (enable input, highlight target)
4. Player Aims & Launches
5. Airplane Flies (physics-based, smooth)
6. Hit Target or Miss
7. TransitionToNextPerson()
├─ Previous Person Reaction (OnTargetHit or OnTargetMissed)
├─ If Success: Remove & Shuffle
├─ If Fail: Keep in queue
├─ Next Person.OnHello()
└─ Wait for completion
8. Repeat from step 3
9. Game Over (no more people)
```
### Shuffle Animation (On Success)
```
Before: [Alice] [Bob] [Charlie] [Diana]
Hit! ↓ ↓ ↓
After: [Bob] [Charlie] [Diana]
(animated slide left)
```
### No Shuffle (On Failure)
```
Before: [Alice] [Bob] [Charlie] [Diana]
Miss! ↓ ↓ ↓
After: [Alice] [Bob] [Charlie] [Diana]
(stays in queue for retry)
```
---
## 🔧 Unity Setup Required
### Inspector Configuration
**1. Create Person GameObjects:**
```
GameObject: "Person_Alice"
Components:
- Person
- Person Name: "Alice"
- Target Name: "TargetA"
- Hello Duration: 1
- Success Duration: 1
- Failure Duration: 1
```
Repeat for Bob, Charlie, etc.
**2. Assign to PersonQueue:**
```
PersonQueue Component:
People In Queue (size 3):
[0] → Drag Person_Alice
[1] → Drag Person_Bob
[2] → Drag Person_Charlie
Shuffle Duration: 0.5
Shuffle Distance: 2
```
**3. Position Person GameObjects:**
- Arrange horizontally in scene
- On success, they'll slide left toward removed person's position
- Spacing should match shuffle distance
---
## 📈 Improvements Summary
| Aspect | Before | After |
|--------|--------|-------|
| **Airplane Movement** | Manual, choppy | Physics-based, smooth |
| **Person Data** | Plain struct | Component with behaviors |
| **Queue Control** | GameManager hardcoded waits | Queue owns transitions |
| **Person Reactions** | None | Awaitable OnHello/Hit/Missed |
| **Shuffle** | None | Animated position transitions |
| **Code Organization** | Mixed responsibilities | Clear ownership |
| **Extensibility** | Limited | Easily add animations/effects |
---
## 🎯 Key Benefits
### For Developers:
1. **Less Boilerplate** - No more hardcoded WaitForSeconds
2. **Clear Ownership** - GameManager = flow, PersonQueue = visuals/timing
3. **Extensible** - Easy to add animations, effects, sounds to Person callbacks
4. **Type-Safe** - Person components instead of loose data
5. **Visual Setup** - Drag person GameObjects in scene, see positioning
### For Designers:
1. **Visible** - People are actual GameObjects in scene
2. **Tweakable** - Timing durations in Inspector
3. **Animatable** - Can attach Animators to Person GameObjects
4. **Flexible** - Easy to adjust shuffle behavior
### For Players:
1. **Smoother** - Physics-based airplane movement
2. **Reactive** - People react to success/failure
3. **Dynamic** - Queue shuffles on success
4. **Polished** - Foundation for rich animations
---
## 🚀 Next Steps
### Immediate (MVP Complete):
1. ✅ Create Person GameObjects in scene
2. ✅ Assign to PersonQueue
3. ✅ Position people horizontally
4. ✅ Test shuffle behavior
### Future Enhancements:
1. **Person Animations**: Add Animator with Hello/Success/Failure states
2. **Visual Effects**: Particles on success, confetti on shuffle
3. **Sound Effects**: Cheers on success, groans on failure
4. **UI Integration**: Show person portrait, name, target indicator
5. **Advanced Shuffle**: More complex choreography, camera tracking
6. **Person Elimination**: Fade out or walk off screen on success
---
## 📝 Testing Checklist
### Physics:
- [ ] Airplane launches smoothly
- [ ] Arc trajectory is natural
- [ ] No stuttering during flight
- [ ] Collision detection works
### Person System:
- [ ] OnHello() called on first person
- [ ] OnTargetHit() called on success
- [ ] OnTargetMissed() called on failure
- [ ] Timing durations respected
### Queue:
- [ ] First person shown at game start
- [ ] Transitions work between people
- [ ] Shuffle animates on success
- [ ] No shuffle on failure
- [ ] People removed from queue on success
- [ ] Game ends when queue empty
### Console Output:
```
[Person] Alice: Hello! I need to hit TargetA!
[AirplaneGameManager] Ready to aim and launch!
... player launches ...
[AirplaneGameManager] ✓ SUCCESS! Hit correct target: TargetA
[Person] Alice: Yes! I hit TargetA!
[PersonQueue] Success! Shuffling remaining people...
[PersonQueue] Removed Alice from queue. Remaining: 2
[Person] Bob: Hello! I need to hit TargetB!
```
---
## ✅ Status: READY FOR TESTING
All code changes are complete and compilation-ready. The airplane minigame now has:
- Smooth physics-based movement
- Rich person behaviors with reactions
- Dynamic queue with shuffle animations
- Clean separation of concerns
- Foundation for extensive polish
**The MVP is complete and ready for Unity scene testing!** 🎉

View File

@@ -1,296 +0,0 @@
# Airplane Interactive Elements - MVP Collection
This collection provides 5 interactive elements (boons and obstacles) for the airplane minigame MVP.
## 📦 Components Overview
### ✅ Positive Effects (Boons)
#### 1. **AirplaneWindZone** - Updraft Helper
**Purpose:** Provides constant upward force to help keep airplane airborne.
**Setup:**
- Add component to GameObject with 2D Collider (Box/Circle)
- Set `Wind Force` to `(0, 5)` for gentle updraft
- Enable `Is World Space` for consistent direction
- Optional: Attach ParticleSystem for visual wind effect
**Use Cases:**
- Updrafts after difficult sections
- Safe zones between obstacles
- Wind tunnels that guide toward target
---
#### 2. **AirplaneBouncySurface** - Trampoline
**Purpose:** Bounces airplane on contact with configurable multiplier.
**Setup:**
- Add component to GameObject with 2D Collider
- Set `Bounce Multiplier` to `1.5` (default) or `2.0` for strong bounce
- Set `Bounce Direction` to `(0, 1)` for upward bounce
- Enable `Use Reflection` to bounce based on impact angle
- Optional: Add Animator and AudioSource for feedback
**Use Cases:**
- Springboards to reach high targets
- Angled bouncers to redirect flight path
- Fun trick shots
---
#### 3. **AirplaneSpeedRing** - Boost Collectible
**Purpose:** Increases velocity when airplane passes through.
**Setup:**
- Add component to GameObject with 2D Circle Collider
- Set `Velocity Multiplier` to `1.5`
- Set `Boost Duration` (currently instant, can be extended)
- Enable `One Time Use` to make it a collectible
- Optional: Add ParticleSystem and AudioSource
**Use Cases:**
- Checkpoint rings along flight path
- Speed boosts before difficult sections
- Collectibles that reward exploration
---
### ❌ Negative Effects (Obstacles)
#### 4. **AirplaneTurbulenceZone** - Chaotic Wind
**Purpose:** Adds random forces that make control unpredictable.
**Setup:**
- Add component to GameObject with 2D Collider (usually Box)
- Set `Turbulence Strength` to `3` (moderate) or `5` (strong)
- Set `Change Frequency` to `0.1` for rapid changes
- Enable `Prevent Upward Force` if you want only downward chaos
- Optional: Add ParticleSystem for swirling effect
**Use Cases:**
- Storm clouds that destabilize flight
- Dangerous zones between safe paths
- Areas that require ability usage to survive
---
#### 5. **AirplaneGravityWell** - Danger Zone
**Purpose:** Pulls airplane toward center, creating hazard to avoid.
**Setup:**
- Add component to GameObject with 2D Circle Collider
- Set `Pull Strength` to `5` (moderate pull)
- Enable `Use Inverse Square` for realistic gravity falloff
- Adjust `Pull Falloff` curve for custom attraction profile
- Optional: Add rotating sprite and particle effect
**Use Cases:**
- Black holes or vortexes to avoid
- Creates skill-based navigation challenges
- Forces players to use abilities to escape
---
## 🎮 Integration with Spawn System
All components check for `AirplaneController` and `IsFlying` status, so they only affect active airplanes.
### Spawning as Obstacles/Boons
To integrate with your existing spawn system:
```csharp
// In AirplaneSpawnManager or similar
public GameObject updraftPrefab;
public GameObject turbulencePrefab;
public GameObject speedRingPrefab;
void SpawnRandomElements(float xPosition)
{
// Randomly spawn helpful or harmful elements
float roll = Random.value;
if (roll < 0.3f)
{
// Spawn updraft (30%)
SpawnElement(updraftPrefab, xPosition);
}
else if (roll < 0.5f)
{
// Spawn turbulence (20%)
SpawnElement(turbulencePrefab, xPosition);
}
else if (roll < 0.7f)
{
// Spawn speed ring (20%)
SpawnElement(speedRingPrefab, xPosition);
}
}
```
---
## 🎨 Visual Setup Recommendations
### Updraft (Wind Zone)
- **Color:** Light blue/cyan
- **Particles:** Upward flowing particles
- **Sound:** Gentle whoosh
### Bouncy Surface
- **Color:** Orange/yellow
- **Animation:** Compress on impact
- **Sound:** "Boing" spring sound
### Speed Ring
- **Color:** Golden yellow
- **Particles:** Spark burst on collect
- **Sound:** Satisfying "ding" or chime
### Turbulence Zone
- **Color:** Dark gray/purple
- **Particles:** Chaotic swirling
- **Sound:** Storm/wind ambience
### Gravity Well
- **Color:** Magenta/purple
- **Particles:** Inward spiral
- **Sound:** Low ominous hum
- **Visual:** Rotating vortex sprite
---
## 🔧 Configuration Tips
### Balancing Positive vs Negative
**For easier gameplay:**
- More updrafts and speed rings
- Weaker turbulence (strength 2-3)
- Smaller gravity wells
**For harder gameplay:**
- Stronger turbulence (strength 5-7)
- Larger gravity wells with higher pull
- Fewer boons, more obstacles
### Placement Strategy
**Good Flow:**
1. Start with safe updrafts
2. Introduce single obstacle (turbulence)
3. Provide speed ring as reward
4. Place gravity well with clear path around it
5. Updraft after dangerous section
**Challenge Flow:**
1. Turbulence → Gravity Well combo
2. Narrow path with bouncy surfaces on sides
3. Speed ring that leads into obstacle (trap!)
4. Multiple gravity wells requiring weaving
---
## 🐛 Debugging
All components have:
- `showDebugLogs` - Enable console logging
- Gizmo visualization in Scene view
- Color-coded for easy identification
**Gizmo Colors:**
- 🟢 Green = Positive force (updraft)
- 🔴 Red = Negative force (downdraft/danger)
- 🟡 Yellow = Neutral/collectible
- 🟠 Orange = Turbulence
- 🟣 Magenta = Gravity well
---
## ⚙️ Advanced Customization
### Wind Zone Variants
**Crosswind (pushes sideways):**
```csharp
windForce = new Vector2(8, 0); // Strong horizontal push
```
**Downdraft (obstacle):**
```csharp
windForce = new Vector2(0, -7); // Downward force
```
**Angled Wind:**
```csharp
windForce = new Vector2(3, 5); // Diagonal force
isWorldSpace = false; // Rotate with transform
```
### Bouncy Surface Variants
**Weak Bounce:**
```csharp
bounceMultiplier = 1.2f;
```
**Super Bounce:**
```csharp
bounceMultiplier = 2.5f;
maxBounceVelocity = 30f;
```
**Angled Bouncer:**
```csharp
bounceDirection = new Vector2(1, 1).normalized; // 45° bounce
useReflection = false;
```
---
## 📊 Performance Considerations
- All components use `OnTriggerStay2D` which is called every physics frame
- Wind and Turbulence zones are most expensive (constant force application)
- Speed rings are cheapest (one-time trigger)
- Consider pooling for frequently spawned elements
- Use `oneTimeUse` on speed rings to auto-cleanup
---
## 🚀 Next Steps for Full Version
**Additional Elements to Consider:**
- Checkpoint Hoops (with score/time bonus)
- Gravity Flip Zones (inverts gravity temporarily)
- Portals (teleportation)
- Spinning Hazards (rotating obstacles)
- Launch Pads (explosive boost)
- Sticky Zones (slow down effect)
**System Improvements:**
- Element spawning rules based on difficulty
- Combination elements (updraft + speed ring)
- Progressive difficulty scaling
- Visual effects library
- Sound effect integration
---
## 📝 Quick Reference Table
| Component | Type | Primary Effect | Strength Range |
|-----------|------|---------------|----------------|
| WindZone | Boon/Obstacle | Constant force | 3-10 |
| BouncySurface | Boon | Velocity reflection | 1.2-2.5x |
| SpeedRing | Boon | Velocity boost | 1.3-2.0x |
| TurbulenceZone | Obstacle | Random chaos | 3-7 |
| GravityWell | Obstacle | Pull to center | 5-15 |
---
**Created:** December 2025
**Version:** 1.0 MVP
**Status:** Ready for Unity integration

View File

@@ -1,484 +0,0 @@
# Airplane Minigame - Unity Setup Guide
**Implementation Status**: ✅ Code Complete
**Setup Time**: ~20 minutes
**Assets Required**: 0 ScriptableObjects (all settings-based!)
---
## What's Been Implemented
### Core Features
**3 Airplane Types** - Jet, Bobbing, Drop (settings-based configuration)
**3 Unique Abilities** - Hold to boost, tap to jump, tap to dive
**Pre-Game Selection UI** - Choose airplane before game starts
**In-Flight Ability Button** - Shows icon, cooldown, and handles input
**Pre-Spawn System** - Airplane visible at slingshot before launch
**Cooldown Management** - Visual fill animation and state tracking
**InputManager Integration** - Proper touch handling (no legacy Input)
**Adaptive Spawning** - Retry keeps same obstacles, success regenerates
**Person Reactions** - Success/failure behaviors with proper sequencing
### Game Flow
```
Game Start → Airplane Selection → Intro → Person Turn → Aiming (airplane at slingshot)
→ Launch → Flying (ability button active) → Hit/Miss → Reaction → Next Person/Retry
```
---
## Unity Setup Steps
### STEP 1: Configure Airplane Settings (5 minutes)
**Location**: `Tools > Settings > Airplane Settings`
You'll see collapsible sections for each airplane type. Configure:
#### **Jet Plane**
```
Display Name: "Jet Plane"
Prefab: [Assign airplane prefab with sprite/model]
Preview Sprite: [Assign for selection UI]
Ability Type: Jet (already set)
Physics Overrides (optional):
☐ Override Mass
☐ Override Gravity Scale
☐ Override Drag
```
#### **Jet Ability**
```
Ability Name: "Jet Boost"
Ability Icon: [Assign sprite for button]
Cooldown Duration: 5.0 seconds
Jet Speed: 15.0
Jet Angle: 0 (flies horizontally)
```
#### **Bobbing Plane**
```
Display Name: "Bobbing Plane"
Prefab: [Assign airplane prefab]
Preview Sprite: [Assign for selection UI]
Ability Type: Bobbing (already set)
Physics Overrides (optional):
☐ Override Mass
☐ Override Gravity Scale
☐ Override Drag
```
#### **Bobbing Ability**
```
Ability Name: "Air Hop"
Ability Icon: [Assign sprite for button]
Cooldown Duration: 3.0 seconds
Bob Jump Force: 10.0
Speed Reduction: 0.7 (70% of original speed)
```
#### **Drop Plane**
```
Display Name: "Drop Plane"
Prefab: [Assign airplane prefab]
Preview Sprite: [Assign for selection UI]
Ability Type: Drop (already set)
Physics Overrides (optional):
☐ Override Mass
☐ Override Gravity Scale
☐ Override Drag
```
#### **Drop Ability**
```
Ability Name: "Dive Bomb"
Ability Icon: [Assign sprite for button]
Cooldown Duration: 4.0 seconds
Drop Force: 20.0
Drop Distance: 5.0
☑ Zero Horizontal Velocity
```
#### **Default Selection**
```
Default Airplane Type: Jet (or your preference)
```
**Note**: If all 3 airplane prefabs are the same, that's fine! The abilities are what differentiate them.
---
### STEP 2: Build Selection UI (10 minutes)
**Create Hierarchy**: `Canvas/AirplaneSelectionPanel`
```
AirplaneSelectionPanel (GameObject)
├── BackgroundImage (Image - semi-transparent dark overlay)
├── TitleText (TextMeshPro)
│ └── Text: "Choose Your Airplane"
├── ButtonContainer (GameObject + Horizontal Layout Group)
│ ├── JetButton (Button)
│ │ ├── Background (Image)
│ │ ├── Icon (Image - jet plane icon)
│ │ └── Label (TextMeshPro: "Jet Plane")
│ ├── BobbingButton (Button)
│ │ ├── Background (Image)
│ │ ├── Icon (Image - bobbing plane icon)
│ │ └── Label (TextMeshPro: "Bobbing Plane")
│ └── DropButton (Button)
│ ├── Background (Image)
│ ├── Icon (Image - drop plane icon)
│ └── Label (TextMeshPro: "Drop Plane")
└── ConfirmButton (Button)
└── Label (TextMeshPro: "Confirm")
```
**Add Component**: `AirplaneSelectionUI` to `AirplaneSelectionPanel`
**Configure Component**:
- Jet Plane Button → Drag `JetButton`
- Bobbing Plane Button → Drag `BobbingButton`
- Drop Plane Button → Drag `DropButton`
- Confirm Button → Drag `ConfirmButton`
- Selected Color: `#FFFF00` (yellow)
- Normal Color: `#FFFFFF` (white)
**Important**: ☑ Set panel **inactive** in Inspector (checkbox next to name)
---
### STEP 3: Build Ability Button (5 minutes)
**Create Hierarchy**: `Canvas/GameplayUI/AbilityButton`
```
AbilityButton (GameObject)
├── ButtonBackground (Image - circular)
├── AbilityIcon (Image - set dynamically)
├── CooldownFill (Image)
│ └── Image Type: Filled
│ └── Fill Method: Radial 360
│ └── Fill Origin: Top
│ └── Clockwise: ☑
└── CooldownText (TextMeshPro - optional)
```
**Add Component**: `AirplaneAbilityButton` to `AbilityButton`
**Configure Component**:
- Button → Drag Button component reference
- Ability Icon → Drag `AbilityIcon` Image
- Cooldown Fill → Drag `CooldownFill` Image
- Cooldown Text → Drag `CooldownText` (optional)
- Ready Color: `#FFFFFF` (white)
- Cooldown Color: `#808080` (gray)
- Active Color: `#FFFF00` (yellow)
**Position**: Bottom-right corner (accessible for thumb on mobile)
**Important**: ☑ Set button **inactive** in Inspector (checkbox next to name)
---
### STEP 4: Wire Game Manager (2 minutes)
**GameObject**: `AirplaneGameManager`
**Assign New References**:
- Selection UI → Drag `AirplaneSelectionPanel`
- Ability Button → Drag `AbilityButton`
**Verify Existing References** (should already be assigned):
- Person Queue
- Camera Manager
- Launch Controller
- Target Validator
- Spawn Manager
---
## Testing Checklist
### Selection UI
- [ ] Panel appears on game start
- [ ] Clicking button highlights it (turns yellow)
- [ ] Confirm button enables after selection
- [ ] Clicking confirm hides panel and starts game
### Airplane Spawning
- [ ] Selected airplane appears at slingshot
- [ ] Airplane stays in place (not falling)
- [ ] Trajectory preview works
- [ ] Launching works correctly
### Jet Ability (Hold to Activate)
- [ ] Button appears after launch with jet icon
- [ ] **Hold button** → Airplane flies straight (no gravity)
- [ ] **Release button** → Gravity returns
- [ ] Cooldown fill animates 1.0 → 0.0
- [ ] Button grays out during cooldown
- [ ] Can use again after cooldown ends
### Bobbing Ability (Tap to Activate)
- [ ] Button appears after launch with bobbing icon
- [ ] **Tap button** → Airplane jumps upward
- [ ] Speed reduces after jump
- [ ] Cooldown starts immediately
- [ ] Can use multiple times per flight
### Drop Ability (Tap to Activate)
- [ ] Button appears after launch with drop icon
- [ ] **Tap button** → Airplane drops straight down
- [ ] Stops dropping after configured distance
- [ ] Cooldown starts after drop ends
- [ ] Can use again after cooldown
### Integration
- [ ] Ability button hides after turn ends
- [ ] Retry uses same airplane type
- [ ] Success switches to next person (can choose again if cycling)
- [ ] No console errors
- [ ] Performance is smooth
---
## How Abilities Work
### Jet Ability - "Jet Boost"
**Input**: Hold button down
**Effect**: Flies straight at constant speed, ignoring gravity
**Duration**: While held (player controlled)
**Cooldown**: After release
**Use Case**: Fly over obstacles, reach distant targets
### Bobbing Ability - "Air Hop"
**Input**: Tap button
**Effect**: Jump upward, lose horizontal speed
**Duration**: Instant
**Cooldown**: After activation
**Use Case**: Gain altitude, avoid low obstacles, extend flight time
### Drop Ability - "Dive Bomb"
**Input**: Tap button
**Effect**: Drop straight down for fixed distance
**Duration**: Until distance reached
**Cooldown**: After drop completes
**Use Case**: Precision strikes, hitting low targets
---
## Architecture Overview
### Settings-Based System (No Assets Required!)
**Old Way** (NOT used):
- Create JetAbility.asset
- Create BobbingAbility.asset
- Create DropAbility.asset
- Create JetPlaneType.asset
- Create BobbingPlaneType.asset
- Create DropPlaneType.asset
- Wire references everywhere
**New Way** (Implemented):
- Configure everything in `AirplaneSettings` (one file!)
- Abilities created at runtime from settings
- Enum-based selection (`AirplaneAbilityType.Jet/Bobbing/Drop`)
- No asset management needed
### Code Structure
```
AirplaneSettings (ScriptableObject)
├─ Jet Plane Config + Jet Ability Config
├─ Bobbing Plane Config + Bobbing Ability Config
└─ Drop Plane Config + Drop Ability Config
AbilityFactory
└─ Creates ability instances from settings at runtime
BaseAirplaneAbility (abstract class)
├─ JetAbility (hold to fly straight)
├─ BobbingAbility (tap to jump)
└─ DropAbility (tap to dive)
Game Flow
├─ AirplaneSelectionUI (choose type)
├─ AirplaneController (initialized with type)
├─ AirplaneAbilityButton (shows during flight)
└─ AbilityFactory (creates ability on demand)
```
### Input System Integration
✅ Uses project's `InputManager` (no legacy Unity Input)
✅ Implements `ITouchInputConsumer` interface
✅ Override consumer registration for priority input
✅ Proper hold/release detection for Jet ability
✅ Works on mobile and desktop
---
## Troubleshooting
### Selection UI doesn't appear
- Check `AirplaneGameManager.selectionUI` is assigned
- Verify panel is inactive by default
- Check console for errors
### Airplane doesn't spawn at slingshot
- Verify prefab is assigned in settings for selected type
- Check `LaunchController` has launch anchor assigned
- Check console for "Cannot spawn" errors
### Ability button doesn't appear
- Verify `AirplaneGameManager.abilityButton` is assigned
- Check button is inactive by default
- Ensure airplane was initialized with type
- Check console for ability creation errors
### Hold doesn't work for Jet ability
- Verify `InputManager` exists in scene
- Check button implements `ITouchInputConsumer`
- Try click-and-hold with mouse first
- Check console for registration messages
### Cooldown fill doesn't animate
- Verify `CooldownFill` Image is assigned
- Check Fill Type is set to "Filled"
- Verify Fill Method is "Radial 360"
- Check fill amount starts at 0
### Wrong airplane spawns
- Check which type was selected in Selection UI
- Verify correct prefab is assigned in settings
- Check console logs for "Selected airplane: [type]"
---
## Advanced Configuration
### Physics Tuning Per Airplane
You can override physics per airplane type in settings:
**Lighter Airplane** (faster, less stable):
```
☑ Override Mass: 0.8
☑ Override Gravity Scale: 0.9
☑ Override Drag: 0.1
```
**Heavier Airplane** (slower, more stable):
```
☑ Override Mass: 1.2
☑ Override Gravity Scale: 1.1
☑ Override Drag: 0.3
```
### Ability Balance
**Make abilities more powerful**:
- Increase Jet Speed (15 → 20)
- Increase Bob Jump Force (10 → 15)
- Increase Drop Force (20 → 30)
**Make abilities have shorter cooldowns**:
- Jet: 5s → 3s
- Bobbing: 3s → 2s
- Drop: 4s → 3s
**Make abilities last longer**:
- Drop Distance: 5 → 8 (drops farther)
---
## Common Questions
**Q: Do I need different airplane prefabs for each type?**
A: No! You can use the same prefab for all three. The abilities differentiate them.
**Q: Can I add a 4th airplane type?**
A: Yes! Add enum value → Create config classes → Add to settings → Update factory. See full docs for details.
**Q: Can I skip the selection UI?**
A: Yes! Leave `selectionUI` unassigned in GameManager. The default type from settings will be used.
**Q: What if I don't assign ability icons?**
A: The button will work but show no icon. It's recommended to assign icons for clarity.
**Q: Can abilities be disabled?**
A: Currently no, but you could set cooldown to 999 to effectively disable them.
**Q: How do I test a specific airplane without the selection UI?**
A: Set the default type in settings, then don't assign the selection UI to GameManager.
---
## Performance Notes
- Abilities are created once per airplane (lightweight)
- Cooldown updates every frame (negligible cost)
- UI updates only during cooldown (efficient)
- No GC allocations during ability use
- Factory pattern avoids reflection overhead
---
## Summary
### What Code Does (Already Implemented)
✅ Manages game state and flow
✅ Creates abilities from settings at runtime
✅ Handles airplane spawning and initialization
✅ Updates cooldowns and ability state
✅ Proper input handling via InputManager
### What You Do (Unity Setup)
1. Configure 3 airplane types + abilities in settings (**5 min**)
2. Build selection UI panel with buttons (**10 min**)
3. Build ability button with cooldown fill (**5 min**)
4. Wire 2 references to GameManager (**2 min**)
5. Test! (**5 min**)
**Total Time: ~27 minutes to full functionality**
---
## Quick Start Checklist
Setup:
- [ ] Open `AirplaneSettings`, configure 3 airplane types
- [ ] Assign prefabs and sprites for all types
- [ ] Assign ability icons for all abilities
- [ ] Set default airplane type
- [ ] Create `AirplaneSelectionPanel` with 3 buttons
- [ ] Add `AirplaneSelectionUI` component, wire buttons
- [ ] Create `AbilityButton` with icon + cooldown fill
- [ ] Add `AirplaneAbilityButton` component, wire references
- [ ] Assign both UI references to `AirplaneGameManager`
- [ ] Set both UI elements inactive by default
Testing:
- [ ] Play → Selection appears
- [ ] Select → Confirm → Airplane spawns
- [ ] Launch → Ability button appears
- [ ] Use ability → Works correctly
- [ ] Cooldown → Animates and resets
- [ ] Turn ends → Button hides
- [ ] Retry → Same airplane
- [ ] Success → Next person
When all checked → System complete! 🎉
---
**Documentation Version**: 1.0
**Last Updated**: December 6, 2025
**Implementation**: Settings-Based Architecture
**Assets Required**: 0 ScriptableObjects ✅

View File

@@ -1 +0,0 @@


View File

@@ -1,353 +0,0 @@
# Airplane Spawn System - Implementation Summary
## Overview
The spawn system dynamically generates targets, positive/negative objects, and ground tiles as the airplane flies through the level. It consists of three main components:
1. **AirplaneSpawnManager** - Core spawning logic
2. **TargetDisplayUI** - Real-time distance display
3. **Settings Integration** - Configurable spawn parameters
## Components Created
### 1. AirplaneSpawnManager
**File**: `Assets/Scripts/Minigames/Airplane/Core/AirplaneSpawnManager.cs`
**Responsibilities**:
- Spawn target at predetermined distance on game start
- Extract target icon sprite for UI display
- Track airplane movement and trigger dynamic spawning after threshold
- Spawn positive/negative objects at random intervals with weighted ratio
- Spawn ground tiles at regular intervals
- Clean up spawned objects between turns
**Key Features**:
- **Target Dictionary**: Serializable array converted to dictionary for fast lookup
- **Weighted Spawning**: Adjusts positive/negative spawn probability to maintain target ratio
- **Threshold-Based**: Spawning only begins when plane crosses configured X position
- **Automatic Icon Extraction**: Finds first SpriteRenderer in target prefab for UI
### 2. TargetDisplayUI
**File**: `Assets/Scripts/Minigames/Airplane/UI/TargetDisplayUI.cs`
**Responsibilities**:
- Display target icon
- Show real-time distance to target
- Update distance as airplane moves
**Key Features**:
- **Performance Optimization**: Updates every N frames (configurable)
- **Flexible Format**: Configurable distance display format string
- **Lifecycle Management**: Hides on start, shows when tracking begins
### 3. Settings Updates
**Files**:
- `Assets/Scripts/Core/Settings/SettingsInterfaces.cs` (IAirplaneSettings)
- `Assets/Scripts/Minigames/Airplane/Settings/AirplaneSettings.cs`
**New Settings Added**:
```csharp
// Spawn System
float DynamicSpawnThreshold // X position where spawning begins
float TargetMinDistance // Min random distance for target
float TargetMaxDistance // Max random distance for target
float ObjectSpawnMinInterval // Min time between object spawns
float ObjectSpawnMaxInterval // Max time between object spawns
float PositiveNegativeRatio // 0-1 ratio (1=all positive, 0=all negative)
float SpawnDistanceAhead // Distance ahead of plane to spawn objects
float GroundSpawnInterval // Distance between ground tiles
```
## Game Flow Integration
### Initialization (SetupNextPerson)
```
SetupNextPerson()
├─ Post-shot reaction (if not first turn)
├─ Get next person
├─ Introduce person
├─ spawnManager.InitializeForGame(targetName)
│ ├─ Determine random target distance
│ ├─ Calculate target spawn position
│ ├─ Spawn target at position
│ ├─ Extract sprite from target
│ └─ Setup UI with sprite and position
├─ Set expected target in validator
└─ Enter aiming state
```
### Launch (HandleAirplaneLaunched)
```
HandleAirplaneLaunched()
├─ Disable launch controller
├─ Change state to Flying
├─ Start camera following airplane
├─ spawnManager.StartTracking(airplane.transform)
│ ├─ Store plane transform
│ ├─ Initialize ground spawn position
│ └─ Start UI tracking (show distance)
└─ Subscribe to airplane events
```
### During Flight (Update Loop)
```
SpawnManager.Update()
├─ Check if plane crossed threshold
│ └─ If yes: Initialize dynamic spawning
├─ If past threshold:
│ ├─ Check spawn timer
│ │ └─ If time: Spawn random object + schedule next
│ └─ Check ground spawn distance
│ └─ If passed: Spawn ground tile + increment position
└─ (UI updates distance every N frames)
```
### Cleanup (EvaluateResult)
```
EvaluateResult()
├─ Stop camera following
├─ spawnManager.StopTracking()
│ └─ Hide UI
├─ Evaluate success/failure
├─ Destroy airplane
├─ spawnManager.CleanupSpawnedObjects()
│ ├─ Destroy all spawned objects
│ ├─ Destroy all ground tiles
│ └─ Destroy spawned target
└─ Continue to next person
```
## Spawning Logic Details
### Target Spawning (Game Start)
1. **Called**: When person's turn begins, before aiming
2. **Distance**: Random between TargetMinDistance and TargetMaxDistance
3. **Position**: `Vector3(distance, 0, 0)` - adjust Y as needed
4. **Icon Extraction**: Searches target and children for first SpriteRenderer
5. **UI Setup**: Passes sprite and position to TargetDisplayUI
### Dynamic Object Spawning (After Threshold)
1. **Trigger**: When plane X position >= DynamicSpawnThreshold
2. **Interval**: Random between ObjectSpawnMinInterval and ObjectSpawnMaxInterval
3. **Type Selection**: Weighted randomness based on PositiveNegativeRatio
- First 5 spawns: Pure random based on ratio
- Subsequent spawns: Adjusts probability to maintain target ratio
4. **Position**: `planePosition + Vector3.right * SpawnDistanceAhead`
5. **Prefab**: Random selection from positive or negative array
### Ground Tile Spawning (After Threshold)
1. **Trigger**: When plane X position >= nextGroundSpawnX
2. **Interval**: Regular distance intervals (GroundSpawnInterval)
3. **Position**: `Vector3(nextGroundSpawnX, 0, 0)` - adjust Y as needed
4. **Prefab**: Random selection from ground tile array
### Weighted Ratio Algorithm
```csharp
// If current ratio is below target:
// Increase positive spawn probability
// If current ratio is above target:
// Decrease positive spawn probability
adjustedProbability = currentRatio < targetRatio
? Lerp(targetRatio, 1.0, (targetRatio - currentRatio) * 2)
: Lerp(0.0, targetRatio, 1 - (currentRatio - targetRatio) * 2);
```
## Unity Setup
### AirplaneSpawnManager Component
**Inspector Fields**:
- **Target Prefabs**: Array of TargetPrefabEntry (key + prefab)
- **Positive Object Prefabs**: Array of prefabs to spawn as positive
- **Negative Object Prefabs**: Array of prefabs to spawn as negative
- **Ground Tile Prefabs**: Array of prefabs to spawn as ground
- **Target Display UI**: Reference to TargetDisplayUI component
- **Spawned Objects Parent**: Optional transform for organization
- **Ground Tiles Parent**: Optional transform for organization
### TargetDisplayUI Component
**Inspector Fields**:
- **Target Icon**: Image component to show target sprite
- **Distance Text**: TextMeshProUGUI to show distance
- **Distance Format**: String format (default: "{0:F1}m")
- **Update Interval**: Frames between updates (default: 5, 0=every frame)
### Scene Hierarchy
```
AirplaneGameManager
├─ PersonQueue
├─ CameraManager
├─ LaunchController
├─ TargetValidator
├─ SpawnManager (NEW)
│ ├─ SpawnedObjects (empty parent)
│ └─ GroundTiles (empty parent)
└─ Canvas
└─ TargetDisplayUI (NEW)
├─ TargetIcon (Image)
└─ DistanceText (TextMeshProUGUI)
```
### Settings Configuration
**Path**: `Tools > Settings > Airplane Settings`
**Spawn System Section**:
- Dynamic Spawn Threshold: 10f
- Target Min Distance: 30f
- Target Max Distance: 50f
- Object Spawn Min Interval: 1f
- Object Spawn Max Interval: 3f
- Positive Negative Ratio: 0.5f (50/50 split)
- Spawn Distance Ahead: 15f
- Ground Spawn Interval: 5f
## Prefab Requirements
### Target Prefabs
- **Must Have**: At least one SpriteRenderer (for icon extraction)
- **Must Have**: Unique key for dictionary lookup
- **Should Have**: Collider2D with "Is Trigger" enabled
- **Should Have**: AirplaneTarget component
### Positive/Negative Object Prefabs
- No specific requirements
- Suggestion: Add Collider2D if you want collision detection
- Suggestion: Add scripts for behavior/scoring
### Ground Tile Prefabs
- No specific requirements
- Suggestion: Size should match GroundSpawnInterval for seamless tiling
## API Reference
### AirplaneSpawnManager
#### Public Methods
```csharp
// Initialize for new game - spawns target, sets up UI
void InitializeForGame(string targetKey)
// Start tracking airplane and enable spawning
void StartTracking(Transform planeTransform)
// Stop spawning and tracking
void StopTracking()
// Clean up all spawned objects
void CleanupSpawnedObjects()
// Get target info (position, distance, sprite)
(Vector3 position, float distance, Sprite icon) GetTargetInfo()
```
### TargetDisplayUI
#### Public Methods
```csharp
// Setup display with target sprite and position
void Setup(Sprite targetSprite, Vector3 targetPosition)
// Start tracking airplane and showing distance
void StartTracking(Transform planeTransform)
// Stop tracking and hide UI
void StopTracking()
// Show/hide UI
void Show()
void Hide()
```
## Testing Checklist
### Pre-Flight
- [ ] Spawn Manager assigned in Game Manager
- [ ] Target prefabs configured with keys matching Person target names
- [ ] Positive/Negative object prefabs assigned
- [ ] Ground tile prefabs assigned
- [ ] Target Display UI created and assigned
- [ ] Settings configured with desired spawn parameters
### In-Game
- [ ] Target spawns at game start at correct distance
- [ ] Target Display UI shows correct icon
- [ ] Distance updates as plane moves
- [ ] Dynamic spawning begins after threshold
- [ ] Objects spawn ahead of plane at intervals
- [ ] Positive/negative ratio maintained over time
- [ ] Ground tiles spawn at regular intervals
- [ ] All spawned objects cleaned up between turns
## Performance Considerations
### Optimizations Included
- UI updates every N frames instead of every frame
- Dictionary lookup for target prefabs (O(1) vs O(n))
- Objects parented for easy batch cleanup
- Single Update loop for all spawning logic
### Potential Issues
- **Too Many Objects**: Adjust spawn intervals or add object pooling
- **Memory Leaks**: CleanupSpawnedObjects destroys everything between turns
- **Spawn Lag**: All spawns are instantaneous - consider staggering if needed
## Extension Points
### Easy Additions
1. **Object Pooling**: Replace Instantiate/Destroy with pool system
2. **Spawn Variety**: Add more object types with different spawn rules
3. **Vertical Spawning**: Add Y-axis randomness to spawn positions
4. **Spawn Waves**: Add wave-based spawning patterns
5. **Distance-Based Difficulty**: Increase spawn frequency as distance increases
6. **Score Integration**: Add scoring when collecting positive/avoiding negative
### Integration with Existing Systems
- **Collision Detection**: Spawned objects can use existing collision systems
- **Audio**: Trigger sounds on spawn using AudioManager
- **VFX**: Add particle effects at spawn positions
- **UI**: Extend TargetDisplayUI to show additional info (score, bonuses, etc.)
## Common Issues & Solutions
### Target Not Spawning
- Check targetKey matches Person.TargetName exactly
- Verify target prefab is assigned in Target Prefabs array
- Check InitializeForGame is called in SetupNextPerson
### Wrong Icon Displayed
- Ensure target prefab has SpriteRenderer component
- Check SpriteRenderer has sprite assigned
- Try adding SpriteRenderer as direct child of target root
### Objects Spawn Too Early/Late
- Adjust DynamicSpawnThreshold setting
- Check plane transform is correctly passed to StartTracking
### Ratio Not Maintained
- Algorithm self-adjusts after first 5 spawns
- Check PositiveNegativeRatio setting (0-1 range)
- Increase spawn count to see ratio converge
### Performance Issues
- Increase TargetDisplayUI.UpdateInterval
- Add object pooling for frequently spawned objects
- Move spawned objects to separate layer for culling
## Future Improvements
### Suggested Enhancements
1. **Procedural Target Placement**: Place targets based on level difficulty
2. **Spawn Patterns**: Predefined patterns for objects (waves, formations)
3. **Environmental Objects**: Non-interactive background objects for depth
4. **Dynamic Ground**: Ground that reacts to plane (dust trails, etc.)
5. **Collectibles**: Special objects that grant bonuses
6. **Obstacles**: Dynamic obstacles that require avoidance
7. **Weather Effects**: Spawned particles for wind, clouds, etc.
8. **Distance Markers**: Visual indicators every X distance
### Advanced Features
1. **Level Data**: Scriptable objects defining spawn sequences
2. **Biomes**: Different visual themes at different distances
3. **Events**: Special spawn events at certain distances
4. **Multipliers**: Chain spawning based on player performance
5. **Achievements**: Track spawn-related statistics

View File

@@ -1,241 +0,0 @@
# AirplaneTypeData - Migration Complete
## What Happened
`AirplaneTypeData.cs` was **deleted** as part of the migration to a **settings-based architecture**. This is intentional and correct.
### Old System (ScriptableObject-based):
```
AirplaneTypeData.cs (ScriptableObject)
├─ DisplayName
├─ Prefab
├─ PreviewSprite
├─ Ability (reference to BaseAirplaneAbility ScriptableObject)
└─ Physics overrides
Required:
- Creating 3 ScriptableObject assets (JetPlaneType, BobbingPlaneType, DropPlaneType)
- Creating 3 ability assets (JetAbility, BobbingAbility, DropAbility)
- Assigning references in Unity Inspector
```
### New System (Settings-based):
```
AirplaneSettings.cs (single asset)
├─ JetPlaneConfig (serializable class)
│ ├─ displayName
│ ├─ prefab
│ ├─ previewSprite
│ ├─ abilityType (enum: Jet)
│ └─ physics overrides
├─ JetAbilityConfig (serializable class)
│ ├─ abilityName
│ ├─ abilityIcon
│ ├─ cooldownDuration
│ ├─ jetSpeed
│ └─ jetAngle
├─ (same structure for Bobbing and Drop)
└─ defaultAirplaneType (enum)
Benefits:
- NO ScriptableObject assets to create
- Everything in ONE settings file
- Enum-based selection (Jet/Bobbing/Drop)
- Abilities created at runtime from config
```
---
## Where Things Are Now
### Configuration Classes
**File**: `Assets/Scripts/Minigames/Airplane/Data/AirplaneAbilityConfig.cs`
Contains:
- `JetAbilityConfig` - Settings for jet ability
- `BobbingAbilityConfig` - Settings for bobbing ability
- `DropAbilityConfig` - Settings for drop ability
- `AirplaneTypeConfig` - Settings for airplane visual/physics
These are `[Serializable]` classes used in `AirplaneSettings`.
### Ability Classes
**Files**:
- `Assets/Scripts/Minigames/Airplane/Abilities/BaseAirplaneAbility.cs` - Abstract base
- `Assets/Scripts/Minigames/Airplane/Abilities/JetAbility.cs` - Jet implementation
- `Assets/Scripts/Minigames/Airplane/Abilities/BobbingAbility.cs` - Bobbing implementation
- `Assets/Scripts/Minigames/Airplane/Abilities/DropAbility.cs` - Drop implementation
These are **regular classes** (not ScriptableObjects) with **constructors** that accept config parameters.
### Factory
**File**: `Assets/Scripts/Minigames/Airplane/Abilities/AbilityFactory.cs`
Creates ability instances from settings:
```csharp
BaseAirplaneAbility ability = AbilityFactory.CreateAbility(
AirplaneAbilityType.Jet,
settings
);
```
### Enum
**File**: `Assets/Scripts/Minigames/Airplane/Data/AirplaneAbilityType.cs`
```csharp
public enum AirplaneAbilityType
{
None,
Jet,
Bobbing,
Drop
}
```
Used throughout the system instead of `AirplaneTypeData` references.
---
## Code Migration Summary
### Updated Files:
1. **AirplaneController.cs**
- `Initialize(AirplaneAbilityType)` instead of `Initialize(AirplaneTypeData)`
- Creates ability via `AbilityFactory.CreateAbility()`
- Removed `currentType` field
2. **AirplaneLaunchController.cs**
- `_selectedAirplaneType` changed from `AirplaneTypeData` to `AirplaneAbilityType`
- `SetAirplaneType(AirplaneAbilityType)` instead of `SetAirplaneType(AirplaneTypeData)`
- Gets config from settings via `settings.GetAirplaneConfig(type)`
3. **AirplaneSelectionUI.cs**
- Removed `[SerializeField] private AirplaneTypeData` fields
- `selectedType` changed from `AirplaneTypeData` to `AirplaneAbilityType`
- Buttons directly pass enum values (e.g., `AirplaneAbilityType.Jet`)
- Events use `Action<AirplaneAbilityType>` instead of `Action<AirplaneTypeData>`
4. **AirplaneGameManager.cs**
- `_selectedAirplaneType` changed from `AirplaneTypeData` to `AirplaneAbilityType`
- Gets default from `settings.DefaultAirplaneType` (returns enum)
- Log statements print enum value directly
5. **AirplaneSettings.cs**
- Added 6 config sections (3 airplane types + 3 abilities)
- Implements `GetAirplaneConfig(type)` method
- Returns appropriate config based on enum
6. **IAirplaneSettings.cs**
- `GetAirplaneConfig(AirplaneAbilityType)` method
- `JetAbilityConfig`, `BobbingAbilityConfig`, `DropAbilityConfig` properties
- `DefaultAirplaneType` returns `AirplaneAbilityType` enum
---
## How to Use
### In Settings (Designer):
1. Open `Tools > Settings > Airplane Settings`
2. Configure sections:
- **Jet Plane** - prefab, sprite, physics
- **Jet Ability** - icon, cooldown, speed, angle
- **Bobbing Plane** - prefab, sprite, physics
- **Bobbing Ability** - icon, cooldown, jump force, speed reduction
- **Drop Plane** - prefab, sprite, physics
- **Drop Ability** - icon, cooldown, force, distance
- **Default Type** - Select Jet/Bobbing/Drop
### In Code:
```csharp
// Get settings
var settings = GameManager.GetSettingsObject<IAirplaneSettings>();
// Get airplane config by type
var config = settings.GetAirplaneConfig(AirplaneAbilityType.Jet);
// Access properties
GameObject prefab = config.prefab;
string displayName = config.displayName;
bool overrideMass = config.overrideMass;
// Create ability
BaseAirplaneAbility ability = AbilityFactory.CreateAbility(
AirplaneAbilityType.Jet,
settings
);
// Initialize airplane with type
airplaneController.Initialize(AirplaneAbilityType.Jet);
```
---
## Migration Impact
### Deleted Files:
-`AirplaneTypeData.cs` - Replaced by `AirplaneTypeConfig` (serializable class in settings)
### Created Files:
-`AirplaneAbilityConfig.cs` - Config classes for all abilities and airplane types
-`AbilityFactory.cs` - Factory for creating abilities from settings
### Modified Files:
-`BaseAirplaneAbility.cs` - Constructor-based instead of ScriptableObject
-`JetAbility.cs` - Constructor-based
-`BobbingAbility.cs` - Constructor-based
-`DropAbility.cs` - Constructor-based
-`AirplaneController.cs` - Uses enum + factory
-`AirplaneLaunchController.cs` - Uses enum + settings
-`AirplaneSelectionUI.cs` - Uses enum, no asset references
-`AirplaneGameManager.cs` - Uses enum
-`AirplaneSettings.cs` - Contains all configs
-`IAirplaneSettings.cs` - Updated interface
---
## Compilation Status
**All errors fixed**
⚠️ Only minor naming convention warnings remain (non-blocking)
### Warnings (Safe to Ignore):
- Field naming conventions (`selectedType` vs `_selectedType`)
- Unused fields (`selectedButton`)
- Redundant qualifiers (`Data.AirplaneAbilityType` vs `AirplaneAbilityType`)
---
## Benefits of New System
1. **Simpler Setup**: 3 steps vs 7 steps (57% faster)
2. **No Asset Management**: Everything in one file
3. **Type-Safe**: Enum-based selection
4. **Runtime Creation**: Abilities instantiated from config
5. **Designer-Friendly**: Collapsible Inspector sections
6. **Easy Extension**: Add new types with minimal code
7. **Single Source of Truth**: All config in AirplaneSettings
8. **No References to Wire**: Settings accessed directly by code
---
## Documentation
Complete documentation available in:
- `docs/airplane_abilities_settings_based.md` - Full technical guide
- `docs/airplane_abilities_unity_quickstart.md` - Setup quick reference
---
## Summary
**`AirplaneTypeData` is gone by design.** The new settings-based system eliminates the need for separate ScriptableObject assets. Everything is now configured in `AirplaneSettings` and airplane types are selected via the `AirplaneAbilityType` enum.
**This is a significant improvement** that reduces setup complexity while maintaining all functionality.

View File

@@ -1 +0,0 @@


View File

@@ -1,281 +0,0 @@
# Airplane Minigame - Unity Setup Quick Reference
## Scene Hierarchy Setup
### 1. Game Manager (Empty GameObject)
- **Name**: `AirplaneGameManager`
- **Component**: `AirplaneGameManager` script
- **Configure**:
- Person Queue: Assign PersonQueue GameObject
- Camera Manager: Assign AirplaneCameraManager GameObject
- Launch Controller: Assign AirplaneLaunchController GameObject
- Target Validator: Assign AirplaneTargetValidator GameObject
- Spawn Manager: Assign AirplaneSpawnManager GameObject
- All Targets: Assign all AirplaneTarget components in scene
### 2. Person Queue (Empty GameObject)
- **Name**: `PersonQueue`
- **Component**: `PersonQueue` script
- **Configure**:
- People In Queue: Assign Person GameObjects in order (index 0 goes first)
- Shuffle Duration: 0.5f (time for people to shuffle when someone succeeds)
- Shuffle Distance: 2f (how far people move during shuffle)
### 3. People (Create one per participant)
- **Name**: Person's name (e.g., "Alice", "Bob", "Charlie")
- **Component**: `Person` script
- **Add Child**: TextMeshPro - Text component for debug messages
- **Configure Person Component**:
- Person Name: Auto-fills from GameObject name
- Target Name: The target this person needs to hit (e.g., "TargetA")
- Debug Text: Assign the TextMeshPro child component
- Show Debug Logs: Optional, for debugging
- **Position**: Place in scene where you want people to stand
### 4. Camera Manager (Empty GameObject)
- **Name**: `AirplaneCameraManager`
- **Component**: `AirplaneCameraManager` script
- **Configure**:
- Intro Camera: Camera for game introduction
- Next Person Camera: Camera for person transitions
- Aiming Camera: Camera for aiming/launching
- Follow Camera: Camera that follows airplane (should have FollowTarget component)
- Blend Duration: 1.0f (camera transition time)
### 5. Launch Controller
- **Name**: `LaunchController`
- **Component**: `AirplaneLaunchController` script (inherits from DragLaunchController)
- **Configure**:
- Airplane Prefab: Assign airplane prefab with AirplaneController
- Launch Point: Where airplane spawns
- Max Drag Distance: Maximum slingshot pull distance
- Launch Force Multiplier: Strength of launch
- Trajectory Preview: Assign TrajectoryPreview component
### 6. Trajectory Preview (Attach to Launch Controller or separate)
- **Component**: `TrajectoryPreview` script
- **Component**: `LineRenderer` (auto-required)
- **Configure**:
- Trajectory Points: 50
- Time Step: 0.1f
- Ground Level: Y position where trajectory stops
- Line Color: Yellow (or preferred color)
- Line Width: 0.1f
### 7. Target Validator (Empty GameObject)
- **Name**: `TargetValidator`
- **Component**: `AirplaneTargetValidator` script
- No configuration needed (targets are set at runtime)
### 8. Spawn Manager (Empty GameObject with child containers)
- **Name**: `SpawnManager`
- **Component**: `AirplaneSpawnManager` script
- **Create Children**:
- `SpawnedObjects` (empty, for organization)
- `GroundTiles` (empty, for organization)
- **Configure**:
- Target Prefabs: Array of target key/prefab pairs
- Key: Must match Person's Target Name (e.g., "TargetA")
- Prefab: Target prefab with SpriteRenderer (for icon)
- Positive Object Prefabs: Array of collectible/good prefabs
- Negative Object Prefabs: Array of obstacle/bad prefabs
- Ground Tile Prefabs: Array of ground/platform prefabs
- Target Display UI: Assign TargetDisplayUI component
- Spawned Objects Parent: Assign SpawnedObjects child
- Ground Tiles Parent: Assign GroundTiles child
### 9. Target Display UI (Canvas child)
- **Name**: `TargetDisplayUI`
- **Component**: `TargetDisplayUI` script
- **Create Children**:
- `TargetIcon` (Image component) - Shows target sprite
- `DistanceText` (TextMeshProUGUI) - Shows distance remaining
- **Configure**:
- Target Icon: Assign TargetIcon Image component
- Distance Text: Assign DistanceText component
- Distance Format: "{0:F1}m" (or preferred format)
- Update Interval: 5 (frames between updates, 0=every frame)
- **Position**: Top corner or preferred UI location
### 10. Targets (Create multiple)
- **Name**: Target identifier (e.g., "TargetA", "TargetB")
- **Component**: `AirplaneTarget` script
- **Component**: `Collider2D` with "Is Trigger" enabled
- **Component**: `SpriteRenderer` (required for icon extraction)
- **Configure AirplaneTarget**:
- Target Name: Unique identifier (e.g., "TargetA")
- Show Debug Logs: Optional
### 11. Airplane Prefab (Create as prefab)
- **Component**: `AirplaneController` script
- **Component**: `Rigidbody2D` set to Kinematic mode (physics calculated manually)
- **Component**: `Collider2D` with "Is Trigger" enabled
- **Configure AirplaneController**:
- Drag Coefficient: 0.01f
- Timeout Duration: 10f (auto-stop after this time)
- Show Debug Logs: Optional
## Settings Configuration
### Airplane Settings Asset
1. Open Settings Window: `Tools > Settings > Airplane Settings`
2. **If not visible**: Add `AirplaneSettings` to `SettingsEditorWindow.cs` (see Settings README)
3. **Configure**:
**Slingshot Settings**:
- Max Drag Distance: 5f
- Launch Force Multiplier: 10f
- Min Launch Force: 2f
- Drag Speed: 5f
- Mass: 1f (projectile mass for trajectory calculations)
**Flight Settings**:
- Airplane Mass: 1f
- Max Flight Time: 10f
**Spawn System** (NEW):
- Dynamic Spawn Threshold: 10f (X position where spawning begins)
- Target Min Distance: 30f
- Target Max Distance: 50f
- Object Spawn Min Interval: 1f (seconds between object spawns)
- Object Spawn Max Interval: 3f
- Positive Negative Ratio: 0.5f (0=all negative, 1=all positive)
- Spawn Distance Ahead: 15f (how far ahead to spawn objects)
- Ground Spawn Interval: 5f (distance between ground tiles)
**Timing**:
- Intro Duration: 1f
- Person Intro Duration: 1f
- Evaluation Duration: 1f
## Testing Checklist
### Pre-Flight Check
- [ ] All Person components have Debug Text assigned
- [ ] PersonQueue has all people assigned in correct order
- [ ] Each Person has a unique Target Name assigned
- [ ] Matching Targets exist in scene with same names
- [ ] Camera Manager has all 4 cameras assigned
- [ ] Launch Controller has Airplane Prefab assigned
- [ ] AirplaneGameManager has all systems assigned
- [ ] Spawn Manager has target prefabs with matching keys
- [ ] Spawn Manager has positive/negative/ground prefabs assigned
- [ ] Target Display UI is created and assigned in Spawn Manager
- [ ] All target prefabs have SpriteRenderer components
### Test Flow
1. **Start Game** → Should blend to intro camera
2. **Introductions** → Each person should display greeting message
3. **First Turn** → Should blend to aiming camera
4. **Target Spawned** → Target appears at configured distance
5. **UI Display** → Target icon and distance shown
6. **Aiming** → Drag to aim, trajectory preview should show
7. **Launch** → Airplane should fly along predicted path
8. **Threshold Cross** → Dynamic spawning begins
9. **Objects Spawn** → Positive/negative objects appear ahead of plane
10. **Ground Spawns** → Ground tiles appear at intervals
11. **Distance Updates** → UI distance decreases as plane approaches
12. **Hit Target** → Person celebrates, gets removed, queue shuffles
13. **Cleanup** → All spawned objects destroyed
14. **Miss Target** → Person shows disappointment, stays in queue
15. **Next Turn** → New target spawned, repeat
16. **Game Over** → When queue is empty
## Common Issues
### Trajectory doesn't match flight path
- Ensure airplane prefab has Rigidbody2D with correct mass
- Verify Slingshot Settings mass matches projectile
- Check gravity scale in Rigidbody2D settings
### People don't show messages
- Assign TextMeshPro component to Debug Text field
- Check that text GameObject is a child of Person
### Camera doesn't follow airplane
- Ensure Follow Camera has FollowTarget component
- Verify AirplaneCameraManager has Follow Camera assigned
### Targets not detected
- Ensure both airplane and targets have Collider2D components
- Set "Is Trigger" on both colliders
- Check layer collision matrix in Project Settings
### Launch doesn't work
- Verify Input Manager is properly configured
- Check Launch Controller is enabled
- Ensure Airplane Prefab is assigned
### Target doesn't spawn
- Check Person's Target Name matches Spawn Manager key exactly
- Verify target prefab is assigned in Target Prefabs array
- Ensure target prefab has SpriteRenderer for icon
### Wrong target icon displayed
- Verify target prefab has SpriteRenderer component
- Check SpriteRenderer has sprite assigned
- Try adding SpriteRenderer as direct child of root
### Objects spawn too early/late
- Adjust Dynamic Spawn Threshold setting
- Check plane transform is passed to StartTracking
### Positive/negative ratio not maintained
- Algorithm self-adjusts after first 5 spawns
- Verify Positive Negative Ratio is 0-1
- Spawn more objects to see ratio converge
### Distance not updating
- Check Target Display UI is assigned in Spawn Manager
- Verify Update Interval is not too high
- Ensure UI is shown when tracking starts
## Script References
### Core Scripts
- `AirplaneGameManager.cs` - Main game orchestrator
- `PersonQueue.cs` - Manages person queue and transitions
- `Person.cs` - Individual person data and reactions
- `AirplaneSpawnManager.cs` - Dynamic spawning system (NEW)
### Gameplay Scripts
- `AirplaneLaunchController.cs` - Handles aiming and launching
- `AirplaneController.cs` - Airplane flight behavior
- `AirplaneTarget.cs` - Target collision detection
- `AirplaneTargetValidator.cs` - Validates hits vs expected targets
### UI Scripts
- `TargetDisplayUI.cs` - Target distance display (NEW)
### Camera Scripts
- `AirplaneCameraManager.cs` - Camera state management
### Common/Shared Scripts
- `DragLaunchController.cs` - Base slingshot mechanics
- `CameraManager<T>.cs` - Generic camera state system
- `TrajectoryPreview.cs` - Visual trajectory prediction
### Settings
- `IAirplaneSettings` - Settings interface
- `AirplaneSettings.cs` - Settings implementation
## Next Steps
1. **Visual Polish**: Replace debug text with proper animations
2. **Audio**: Add sound effects for launch, hit, miss, celebrations, spawns
3. **VFX**: Add particle effects for launch, flight trail, hit impact, spawns
4. **UI**: Add score display, turn counter, success rate, combo meter
5. **Targets**: Add visual feedback when hit/missed
6. **People**: Add character models and animations
7. **Airplane**: Add proper airplane model with flight animations
8. **Spawned Objects**: Add collision/scoring logic to positive/negative objects
9. **Ground Tiles**: Add seamless scrolling ground system
10. **Power-ups**: Add special spawned objects with unique effects
## Additional Documentation
For detailed information about the spawn system:
- See `docs/airplane_spawn_system_guide.md` for complete spawn system documentation
- See `docs/person_integration_summary.md` for person queue system
- See `docs/airplane_implementation_summary.md` for overall architecture

View File

@@ -1,350 +0,0 @@
# ✅ Common Trajectory Preview Implementation Complete
## Summary
Created a **single common `TrajectoryPreview` component** that both FortFight and Airplane minigames now use. The base `DragLaunchController` class holds the trajectory preview reference and handles all visual feedback automatically.
---
## What Was Accomplished
### 1. Created Common TrajectoryPreview Component ✅
**File:** `Assets/Scripts/Common/Visual/TrajectoryPreview.cs`
**Features:**
- Single, reusable component for all slingshot mechanics
- Multiple API overloads for different use cases
- LineRenderer-based visualization
- Trajectory locking support (show path after launch)
- Ground detection
- Configurable appearance (color, width, points, timeStep)
**API Overloads:**
```csharp
// 1. Most explicit - pass everything
UpdateTrajectory(Vector2 startPos, Vector2 velocity, float gravity)
// 2. From launch parameters
UpdateTrajectory(Vector2 startPos, Vector2 direction, float force, float mass, float gravity)
// 3. From prefab Rigidbody2D (RECOMMENDED - auto-reads physics)
UpdateTrajectory(Vector2 startPos, Vector2 direction, float force, GameObject prefab)
```
### 2. Updated DragLaunchController Base Class ✅
**Added:**
- `protected TrajectoryPreview trajectoryPreview` field
- Auto-finds TrajectoryPreview component if not assigned
- Default implementations of ShowPreview(), HidePreview(), UpdateVisuals()
- Base class handles ALL trajectory logic automatically
**How It Works:**
```csharp
// Base class in UpdateDrag():
UpdateVisuals(currentPosition, direction, force, dragDistance, mass);
// Default UpdateVisuals implementation:
protected virtual void UpdateVisuals(...)
{
if (trajectoryPreview != null && dragDistance > 0.1f)
{
GameObject prefab = GetProjectilePrefab();
trajectoryPreview.UpdateTrajectory(launchAnchor.position, direction, force, prefab);
}
}
```
### 3. Simplified FortFight SlingshotController ✅
**Removed:**
- `private TrajectoryPreview trajectoryPreview` field (now in base)
- `ShowPreview()` override (base handles it)
- `HidePreview()` override (base handles it)
- `UpdateVisuals()` override (base handles it)
- `OnManagedStart()` method (base handles trajectory init)
**Code Reduction:** ~50 lines removed
**Still Has:**
- Ammo system
- AI methods
- Trajectory locking (calls `trajectoryPreview.LockTrajectory()` after launch)
### 4. Simplified Airplane LaunchController ✅
**Removed:**
- `private LineRenderer trajectoryLine` field
- `private GameObject anchorVisual` field
- Entire `Visual Feedback` region (~100 lines)
- `UpdateTrajectoryPreview()` private method (~30 lines)
- `ShowPreview()` override
- `HidePreview()` override
- `UpdateVisuals()` override
**Code Reduction:** ~130 lines removed
**Now Uses:** Base class default implementations exclusively
---
## Architecture
```
TrajectoryPreview (Common.Visual)
├── LineRenderer component
├── Multiple UpdateTrajectory() overloads
├── Show() / Hide() / LockTrajectory()
└── Kinematic trajectory calculation
DragLaunchController (Common.Input)
├── protected TrajectoryPreview trajectoryPreview
├── Auto-finds component
├── Default implementations:
│ ├── ShowPreview() → trajectoryPreview?.Show()
│ ├── HidePreview() → trajectoryPreview?.Hide()
│ └── UpdateVisuals() → trajectoryPreview.UpdateTrajectory(...)
└── Children can override if needed
SlingshotController (FortFight)
├── Uses inherited trajectoryPreview
├── No trajectory code needed
└── Just implements PerformLaunch()
AirplaneLaunchController (Airplane)
├── Uses inherited trajectoryPreview
├── No trajectory code needed
└── Just implements PerformLaunch()
```
---
## Files Modified
1.**Created:** `Common/Visual/TrajectoryPreview.cs` - Common component (~220 lines)
2.**Modified:** `Common/Input/DragLaunchController.cs` - Added trajectory field and default implementations
3.**Modified:** `Minigames/FortFight/Core/SlingshotController.cs` - Removed ~50 lines
4.**Modified:** `Minigames/Airplane/Core/AirplaneLaunchController.cs` - Removed ~130 lines
**Total Code Reduction:** ~180 lines removed, common implementation added (~220 lines)
**Net Change:** +40 lines total, but **-360 lines of duplicate code** consolidated into one place
---
## Compilation Status
**Zero errors!** All files compile successfully.
**Minor Warnings:**
- Unused using directives (cleanup)
- Redundant default initializers (style)
---
## Unity Scene Setup
### For FortFight (Existing Scenes)
**Current State:**
- Has old `TrajectoryPreview` component (from `Minigames.FortFight.Core`)
**Migration Options:**
**Option A: Replace Component (Recommended)**
1. Select slingshot GameObject
2. Remove old `FortFight.Core.TrajectoryPreview` component
3. Add new `Common.Visual.TrajectoryPreview` component
4. Configure visual settings (color, width, points)
5. Base class will auto-find it
**Option B: Keep Old Component (Compatibility)**
- Old `FortFight.Core.TrajectoryPreview` still exists in project
- Can keep using it temporarily
- But it won't get new improvements
- Eventually should migrate to common version
### For Airplane (New Scenes)
**Setup:**
1. Select launch controller GameObject
2. Add `Common.Visual.TrajectoryPreview` component
3. Add `LineRenderer` component (auto-required)
4. Configure trajectory settings:
- Trajectory Points: 20
- Time Step: 0.1
- Line Color: Yellow
- Line Width: 0.1
5. Base class will auto-find it
### Inspector Fields
**DragLaunchController now has:**
- `Launch Anchor` - spawn point (required)
- `Trajectory Preview` - optional, auto-finds if not assigned
**No inspector fields needed in subclasses for trajectory!**
---
## API Usage Examples
### From Game Code (If Needed)
```csharp
// Access trajectory preview from controller
trajectoryPreview.SetTrajectoryPoints(30); // Change point count
trajectoryPreview.SetTimeStep(0.05f); // Change time step
trajectoryPreview.LockTrajectory(2f); // Lock for 2 seconds
// Manual trajectory update (rare - base class handles this)
trajectoryPreview.UpdateTrajectory(
startPos,
direction,
force,
projectilePrefab // Reads Rigidbody2D automatically
);
```
### For New Minigames
```csharp
public class MyLauncher : DragLaunchController
{
protected override SlingshotConfig GetSlingshotConfig()
{
return mySettings.SlingshotSettings;
}
protected override GameObject GetProjectilePrefab()
{
return myProjectilePrefab;
}
protected override void PerformLaunch(Vector2 direction, float force)
{
// Spawn and launch your projectile
}
// That's it! Trajectory preview works automatically.
// Base class handles: ShowPreview, HidePreview, UpdateVisuals
}
```
---
## Benefits
**Single Implementation** - One trajectory calculation, one place to fix bugs
**Less Code** - ~180 lines removed from game-specific controllers
**Easier Maintenance** - Change trajectory logic in one place
**Reusable** - Any future slingshot minigame gets it free
**Flexible API** - Multiple overloads for different use cases
**Automatic** - Base class handles everything, subclasses do nothing
**Accurate** - Reads physics directly from prefab's Rigidbody2D
**Configurable** - Visual settings in one component
---
## Migration Path for FortFight
### Immediate (Can Do Now)
1. Old `FortFight.Core.TrajectoryPreview` still exists and works
2. No breaking changes to existing scenes
3. SlingshotController is compatible with both old and new component
### Future (Recommended)
1. Replace old component with new `Common.Visual.TrajectoryPreview`
2. Delete old `Minigames/FortFight/Core/TrajectoryPreview.cs` file
3. Clean up any references
### Why Migrate?
- Future improvements go to common version only
- Old version reads gravity from settings (deprecated)
- New version reads gravity from prefab's Rigidbody2D (accurate)
- Consistency across all minigames
---
## Testing Checklist
### FortFight
- [ ] Trajectory preview shows during drag
- [ ] Trajectory updates as you pull back
- [ ] Trajectory locks after launch (shows for 2 seconds)
- [ ] Different ammo types have different trajectories
- [ ] Heavy projectiles have steeper arcs
- [ ] Trajectory matches actual flight path
### Airplane
- [ ] Add TrajectoryPreview component to scene
- [ ] Trajectory preview shows during drag
- [ ] Trajectory matches actual airplane flight
- [ ] Preview hides when released
- [ ] Prefab's Rigidbody2D mass and gravityScale are used
### General
- [ ] No errors in console
- [ ] Trajectory calculation is smooth
- [ ] Colors and width are configurable
- [ ] Line renderer appears/disappears correctly
---
## Old vs New Comparison
| Aspect | Before | After |
|--------|--------|-------|
| **Trajectory Code Location** | 2 places (FortFight + Airplane) | 1 place (Common) |
| **Lines of Code** | ~230 (duplicated) | ~220 (common) + 0 in games |
| **FortFight Controller** | ~300 lines | ~250 lines |
| **Airplane Controller** | ~220 lines | ~90 lines |
| **Maintenance** | Fix bugs in 2 places | Fix bugs in 1 place |
| **New Minigames** | Copy/paste trajectory code | Add component, done |
| **Gravity Calculation** | From settings (FortFight), inline (Airplane) | From prefab Rigidbody2D |
| **API** | Internal, game-specific | Public, reusable overloads |
---
## Future Enhancements (Easy to Add Now)
Since trajectory is centralized, we can easily add:
- **Different Visualization Styles** (dots, dashed, solid)
- **Collision Preview** (show where trajectory hits)
- **Wind Effects** (add wind vector to calculation)
- **Multiple Trajectories** (show min/max arc range)
- **Performance Optimizations** (LOD, caching)
- **Custom Materials** (glow, fade, animated)
All of these would benefit **every minigame** automatically!
---
## Conclusion
**Goal State Achieved:**
✅ One common trajectory preview component
✅ Easy-to-use API with multiple overloads
✅ Used by both FortFight and Airplane controllers
✅ Base class handles everything automatically
✅ Subclasses have minimal code
✅ No duplicate trajectory logic
✅ Reads physics directly from prefabs
✅ Zero compilation errors
**Status:** Ready for Unity testing!
**Next Step:** Add `Common.Visual.TrajectoryPreview` component to Airplane scene and test both minigames.
---
**Date:** December 4, 2025
**Implementation Time:** ~30 minutes
**Files Created:** 1
**Files Modified:** 3
**Code Reduction:** ~180 lines
**Compilation Errors:** 0

View File

@@ -1 +0,0 @@