الضرر النطاقي
الدرس 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) إلى تدميرها بعد ذلك التأخير، من دون الحاجة إلى مؤقت خاص بك.
التحدي
متوسطتنفجر قذائف المدفع وتؤذي كل عدو قريب.
- في
TowerData، أضفpublic float splashRadius;(يضبط CannonData القيمة على 1.5). يأخذLaunchوسيطًا ثالثًا، وهوTowerData data، ويمرره Tower. - عند الوصول، إذا كان
data.splashRadius > 0، يتلقى كل عنصر IDamageable فيPhysics.OverlapSphere(transform.position, data.splashRadius)الضرر مرة واحدة؛ وإلا، فالهدف وحده. - ثم اعرض هناك
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