Files
AppleHillsProduction/docs/airplane_spawn_system_guide.md

354 lines
12 KiB
Markdown
Raw Normal View History

2025-12-05 16:24:44 +01:00
# 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