התזה
שיעור 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: הגנת מגדלים
תרגלו בעצמכם: Unity אונליין