private void Awake() { _damageable = this.GetComponentOrThrow <Damageable>(); _damageable.OnDamageEvent.AddListener(this.OnDamaged); }
public static void InflictDamageToObjectsInArea( Vector3 center, float radius, float damageAmount, AnimationCurve damageOverDistanceCurve, string damageType, object attacker = null, object attackingPlayer = null) { Collider[] overlappingColliders = Physics.OverlapSphere(center, radius); var damagables = new Dictionary <Damageable, List <Collider> >(); foreach (var collider in overlappingColliders) { var damagable = collider.GetComponentInParent <Damageable>(); if (damagable != null) { if (damagables.ContainsKey(damagable)) { damagables[damagable].Add(collider); } else { damagables.Add(damagable, new List <Collider>() { collider }); } } } foreach (var pair in damagables) { Damageable damageable = pair.Key; List <Collider> colliders = pair.Value; // find closest point from all colliders float closestPointDistance = float.MaxValue; foreach (var collider in colliders) { Vector3 closestPointOnCollider = collider.ClosestPointOrBoundsCenter(center); float distanceToPointOnCollider = Vector3.Distance(center, closestPointOnCollider); if (distanceToPointOnCollider < closestPointDistance) { closestPointDistance = distanceToPointOnCollider; } } // apply damage based on closest distance float distance = closestPointDistance; float distanceFactor = damageOverDistanceCurve.Evaluate(Mathf.Clamp01(distance / radius)); float damageAmountBasedOnDistance = damageAmount * distanceFactor; F.RunExceptionSafe(() => damageable.Damage(new DamageInfo { amount = damageAmountBasedOnDistance, damageType = damageType, attacker = attacker, attackingPlayer = attackingPlayer, })); } }