private void AddAffectedObjects(int colliderCount, ExplosiveDamage explosiveDamage, float chipAwayPercentage) { for (int i = 0; i < colliderCount; i++) { Collider col = DestructionManager.Instance.overlapColliders[i]; // Ignore terrain colliders if (col is TerrainCollider) { continue; } // Ignore self (the rocket) if (col == GetComponent <Collider>()) { continue; } // Check for Rigidbodies Rigidbody rbody = col.attachedRigidbody; if (rbody != null && !rbody.isKinematic && !affectedRigidbodies.Contains(rbody)) { affectedRigidbodies.Add(rbody); } // Check for Chip-Away Debris ChipAwayDebris chipAwayDebris = col.gameObject.GetComponent <ChipAwayDebris>(); if (chipAwayDebris != null && !affectedChipAwayDebris.ContainsKey(chipAwayDebris)) { affectedChipAwayDebris.Add(chipAwayDebris, chipAwayPercentage); } if (chipAwayDebris != null) { continue; // Don't process destructible components on chip-away debris. } // Check for Destructible objects Destructible destructible = col.gameObject.GetComponentInParent <Destructible>(); if (destructible != null && !affectedDestructibles.ContainsKey(destructible)) { affectedDestructibles.Add(destructible, explosiveDamage); } } }
public void Explode() { Vector3 currPos = transform.position; isExploding = true; TurnOffSmokeTrail(); // Play explosion particle effect. ObjectPool.Instance.Spawn(explosionPrefab, currPos, GetComponent <Rigidbody>().rotation); // POINT BLANK RANGE - Apply force and damage to colliders and rigidbodies int pointBlankCounter = Physics.OverlapSphereNonAlloc(currPos, pointBlankBlastRadius, DestructionManager.Instance.overlapColliders); ExplosiveDamage pointBlankExplosiveDamage = new ExplosiveDamage() { Position = currPos, DamageAmount = blastDamage * pointBlankDamagePercent, BlastForce = blastForce, Radius = farBlastRadius, UpwardModifier = explosionUpwardPush }; AddAffectedObjects(pointBlankCounter, pointBlankExplosiveDamage, .75f); // NEAR RANGE - Apply force and damage to colliders and rigidbodies int nearCounter = Physics.OverlapSphereNonAlloc(currPos, nearBlastRadius, DestructionManager.Instance.overlapColliders); ExplosiveDamage nearExplosiveDamage = new ExplosiveDamage() { Position = currPos, DamageAmount = blastDamage * nearDamagePercent, BlastForce = blastForce, Radius = farBlastRadius, UpwardModifier = explosionUpwardPush }; AddAffectedObjects(nearCounter, nearExplosiveDamage, .50f); // FAR RANGE - Apply force and damage to colliders and rigidbodies int farCounter = Physics.OverlapSphereNonAlloc(currPos, farBlastRadius, DestructionManager.Instance.overlapColliders); ExplosiveDamage farExplosiveDamage = new ExplosiveDamage() { Position = currPos, DamageAmount = blastDamage * farDamagePercent, BlastForce = blastForce, Radius = farBlastRadius, UpwardModifier = explosionUpwardPush }; AddAffectedObjects(farCounter, farExplosiveDamage, .25f); // Apply blast force to all affected rigidbodies foreach (Rigidbody rbody in affectedRigidbodies) { rbody.AddExplosionForce(blastForce, transform.position, farBlastRadius, explosionUpwardPush); // NOTE: farBlastRadius is used because we need the max radius for rigidbody force. } // Apply blast to ChipAwayDebris foreach (KeyValuePair <ChipAwayDebris, float> chipAwayDebris in affectedChipAwayDebris) { if (Random.Range(1, 100) <= 100 * chipAwayDebris.Value) // Chip off debris pieces a fraction of the time, depending on how close they were to the blast point. { chipAwayDebris.Key.BreakOff(blastForce, farBlastRadius, explosionUpwardPush); } } // Apply blast to Destructibles foreach (KeyValuePair <Destructible, ExplosiveDamage> destructible in affectedDestructibles) { if (destructible.Value.DamageAmount > 0f) { destructible.Key.ApplyDamage(destructible.Value); } } StartCoroutine(Recover()); }