354 lines
12 KiB
Markdown
354 lines
12 KiB
Markdown
|
|
# 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
|
||
|
|
|