using Core; using Core.Lifecycle; using Core.Settings; using UnityEngine; namespace Minigames.BirdPooper { /// /// Poop projectile that falls straight down with manual gravity. /// Destroys when off-screen or hitting targets (Phase 5). /// [RequireComponent(typeof(Rigidbody2D))] [RequireComponent(typeof(Collider2D))] public class PoopProjectile : ManagedBehaviour { private IBirdPooperSettings settings; private float verticalVelocity; // Current downward velocity private const float GravityAcceleration = 20f; // Gravity acceleration (units/s²) internal override void OnManagedAwake() { base.OnManagedAwake(); // Tag as Projectile for target detection if (!gameObject.CompareTag("Projectile")) { gameObject.tag = "Projectile"; } // Load settings settings = GameManager.GetSettingsObject(); if (settings == null) { Debug.LogError("[PoopProjectile] BirdPooperSettings not found!"); Destroy(gameObject); return; } // Initialize velocity with settings speed as starting velocity verticalVelocity = settings.PoopFallSpeed; // Verify Rigidbody2D configuration Rigidbody2D rb = GetComponent(); if (rb != null) { rb.bodyType = RigidbodyType2D.Kinematic; // Kinematic = manual control, no physics rb.collisionDetectionMode = CollisionDetectionMode2D.Continuous; } // Find and set all colliders to trigger (we use OnTriggerEnter2D) Collider2D[] colliders = GetComponentsInChildren(true); foreach (Collider2D col in colliders) { if (!col.isTrigger) { col.isTrigger = true; Debug.Log($"[PoopProjectile] Set collider '{col.name}' to trigger"); } } } private void Update() { if (settings != null) { ApplyGravity(); FallDown(); CheckBounds(); } } /// /// Apply gravity acceleration to velocity. /// private void ApplyGravity() { // Increase downward velocity over time (gravity acceleration) verticalVelocity += GravityAcceleration * Time.deltaTime; } /// /// Manual downward movement using current velocity. /// private void FallDown() { // Move straight down at current velocity transform.position += Vector3.down * verticalVelocity * Time.deltaTime; } /// /// Check if projectile is off-screen and should be destroyed. /// private void CheckBounds() { if (transform.position.y < settings.PoopDestroyYPosition) { Destroy(gameObject); } } /// /// Trigger collision detection for targets (Phase 5). /// Uses OnTriggerEnter2D with trigger collider. /// private void OnTriggerEnter2D(Collider2D other) { if (other.CompareTag("Target")) { // Notify target it was hit Target target = other.GetComponent(); if (target != null) { target.OnHitByProjectile(); } Destroy(gameObject); } } } }