示例#1
0
 private void Awake()
 {
     _damageable = this.GetComponentOrThrow <Damageable>();
     _damageable.OnDamageEvent.AddListener(this.OnDamaged);
 }
示例#2
0
        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,
                }));
            }
        }