using System.Collections.Generic; using UnityEngine; namespace Unity.FPS.Game { public class DamageArea : MonoBehaviour { [Tooltip("Area of damage when the projectile hits something")] public float AreaOfEffectDistance = 5f; [Tooltip("Damage multiplier over distance for area of effect")] public AnimationCurve DamageRatioOverDistance; [Header("Debug")] [Tooltip("Color of the area of effect radius")] public Color AreaOfEffectColor = Color.red * 0.5f; public void InflictDamageInArea(float damage, Vector3 center, LayerMask layers, QueryTriggerInteraction interaction, GameObject owner) { Dictionary uniqueDamagedHealths = new Dictionary(); // Create a collection of unique health components that would be damaged in the area of effect (in order to avoid damaging a same entity multiple times) Collider[] affectedColliders = Physics.OverlapSphere(center, AreaOfEffectDistance, layers, interaction); foreach (var coll in affectedColliders) { Damageable damageable = coll.GetComponent(); if (damageable) { Health health = damageable.GetComponentInParent(); if (health && !uniqueDamagedHealths.ContainsKey(health)) { uniqueDamagedHealths.Add(health, damageable); } } } // Apply damages with distance falloff foreach (Damageable uniqueDamageable in uniqueDamagedHealths.Values) { float distance = Vector3.Distance(uniqueDamageable.transform.position, transform.position); uniqueDamageable.InflictDamage( damage * DamageRatioOverDistance.Evaluate(distance / AreaOfEffectDistance), true, owner); } } void OnDrawGizmosSelected() { Gizmos.color = AreaOfEffectColor; Gizmos.DrawSphere(transform.position, AreaOfEffectDistance); } } }