Menu
CoddyTech

الضرر النطاقي

الدرس 20 من 25 في دورة لعبة Unity: الدفاع عن الأبراج على Coddy.

تنفجر قذيفة المدفع عند ارتطامها وتلحق الضرر بكل عدو قريب من الانفجار، وليس بالهدف وحده. تُرجع Physics.OverlapSphere(center, radius) كل مصادم يقع ضمن radius من center: الأعداء، وكذلك الأرض والمسار. كل مصادم لديه IDamageable يتلقى الضرر. والهدف واحد منهم، لأن القذيفة ترتطم به، لذا يجب ألا يتلقى الضرر مرة ثانية بمفرده. قنبلة تدفع كل صندوق حولها:

void Explode()
{
    foreach (Collider other in Physics.OverlapSphere(transform.position, blastRadius))
    {
        if (other.TryGetComponent(out Rigidbody body))
        {
            Vector3 away = (body.position - transform.position).normalized;
            body.AddForce(away * push, ForceMode.Impulse);
        }
    }
}

نصف قطر الانفجار جزء من بيانات المدفع، لذا يحتاج المقذوف الآن إلى أكثر من قيمة للضرر: تتلقى Launch أيضًا بيانات TowerData الخاصة بالبرج. نصف قطر انفجار السهم هو 0، لذا تظل طلقاته تصيب هدفها وحده. ويبقى الضرر وسيطًا منفصلًا، لأنه يعتمد على مستوى البرج.

يوضح الانفجار للاعب مكان ارتطام القذيفة: كرة شفافة بعرض منطقة الانفجار، تختفي بعد ربع ثانية. يؤدي Destroy(blast, 0.25f) إلى تدميرها بعد ذلك التأخير، من دون الحاجة إلى مؤقت خاص بك.

challenge icon

التحدي

متوسط

تنفجر قذائف المدفع وتؤذي كل عدو قريب.

  1. في TowerData، أضف public float splashRadius; (يضبط CannonData القيمة على 1.5). يأخذ Launch وسيطًا ثالثًا، وهو TowerData data، ويمرره Tower.
  2. عند الوصول، إذا كان data.splashRadius > 0، يتلقى كل عنصر IDamageable في Physics.OverlapSphere(transform.position, data.splashRadius) الضرر مرة واحدة؛ وإلا، فالهدف وحده.
  3. ثم اعرض هناك blastPrefab مُسلسَلًا، واضبط حجمه باستخدام Vector3.one * data.splashRadius * 2f، ثم نفّذ Destroy(blast, 0.25f).

اضغط «العب»: يؤذي انفجار المدفع مجموعات الـGrunts المتقاربة. ثم اضغط «تحقق».

جرّب بنفسك

using UnityEngine;

public class Projectile : MonoBehaviour
{
    [SerializeField] private float speed = 12f;

    private Transform target;
    private int damage;

    public void Launch(Transform target, int damage)
    {
        this.target = target;
        this.damage = damage;
    }

    void Update()
    {
        if (target == null)
        {
            Destroy(gameObject);
            return;
        }

        transform.position = Vector3.MoveTowards(transform.position, target.position, speed * Time.deltaTime);
        if (transform.position == target.position)
        {
            if (target.TryGetComponent(out IDamageable damageable))
            {
                damageable.TakeDamage(damage);
            }
            Destroy(gameObject);
        }
    }
}

جميع دروس لعبة Unity: الدفاع عن الأبراج

تدرّب بنفسك: Playground لـ Unity