using Core; using UnityEngine; namespace Minigames.FortFight.Projectiles { /// /// Trash Bag projectile - splits into multiple smaller pieces on impact. /// Deals AOE damage in a forward cone. /// public class TrashBagProjectile : ProjectileBase { [Header("Trash Bag Specific")] [Tooltip("Prefab for individual trash pieces (small debris)")] [SerializeField] private GameObject trashPiecePrefab; protected override void OnHit(Collision2D collision) { // Deal initial damage from trash bag itself var block = collision.gameObject.GetComponent(); if (block != null) { block.TakeDamage(Damage); Logging.Debug($"[TrashBagProjectile] Dealt {Damage} damage to {block.gameObject.name}"); } // Get settings for trash pieces var settings = GameManager.GetSettingsObject(); int pieceCount = settings?.TrashBagPieceCount ?? 8; Logging.Debug($"[TrashBagProjectile] Splitting into {pieceCount} pieces"); // Get contact normal and impact point Vector2 hitNormal = collision.contacts[0].normal; Vector2 impactPoint = collision.contacts[0].point; // Spawn trash pieces (NOT parented, so they persist as debris) SpawnTrashPieces(impactPoint, hitNormal); // Destroy trash bag after spawning pieces DestroyProjectile(); } /// /// Spawn multiple trash pieces in a cone away from the hit surface. /// Uses hit normal + projectile momentum for realistic splash effect. /// private void SpawnTrashPieces(Vector2 impactPoint, Vector2 hitNormal) { if (trashPiecePrefab == null) { Logging.Warning("[TrashBagProjectile] No trash piece prefab assigned!"); return; } // Get settings var settings = GameManager.GetSettingsObject(); int pieceCount = settings?.TrashBagPieceCount ?? 8; float pieceForce = settings?.TrashBagPieceForce ?? 10f; float spreadAngle = settings?.TrashBagSpreadAngle ?? 60f; // Calculate projectile's incoming direction (momentum) Vector2 incomingDirection = rb2D.linearVelocity.normalized; if (incomingDirection == Vector2.zero) { incomingDirection = LaunchDirection; } // Calculate reflection direction from hit normal // This creates a bounce-like effect Vector2 reflectDirection = Vector2.Reflect(incomingDirection, hitNormal); // Blend between reflection and pure normal for more variety // 70% normal (splash away from surface) + 30% reflection (maintain some momentum direction) Vector2 baseDirection = (hitNormal * 0.7f + reflectDirection * 0.3f).normalized; // Spawn pieces in a cone around the base direction for (int i = 0; i < pieceCount; i++) { // Calculate angle offset for this piece within the spread cone float t = pieceCount > 1 ? i / (float)(pieceCount - 1) : 0.5f; float angleOffset = Mathf.Lerp(-spreadAngle / 2f, spreadAngle / 2f, t); float angleRadians = Mathf.Atan2(baseDirection.y, baseDirection.x) + angleOffset * Mathf.Deg2Rad; Vector2 pieceDirection = new Vector2(Mathf.Cos(angleRadians), Mathf.Sin(angleRadians)); // Spawn trash piece slightly offset from impact point Vector2 spawnOffset = pieceDirection * 0.2f; // Small offset to prevent clipping GameObject piece = Instantiate(trashPiecePrefab, (Vector2)impactPoint + spawnOffset, Quaternion.identity); // Setup trash piece physics Rigidbody2D pieceRb = piece.GetComponent(); if (pieceRb != null) { // Apply force with some randomness for more natural spread float randomForce = pieceForce * Random.Range(0.8f, 1.2f); pieceRb.AddForce(pieceDirection * randomForce, ForceMode2D.Impulse); // Add some random spin pieceRb.AddTorque(Random.Range(-100f, 100f)); } Logging.Debug($"[TrashBagProjectile] Spawned trash piece {i} in direction {pieceDirection}"); } } } }