# 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